Rename khepri -> restic

This commit is contained in:
Alexander Neumann 2014-12-05 21:45:49 +01:00
parent 9dc0bf6378
commit e2fea0d088
41 changed files with 181 additions and 181 deletions

View File

@ -7,7 +7,7 @@ test:
for dir in cmd/* ; do \ for dir in cmd/* ; do \
(cd "$$dir"; go build $(FLAGS)) \ (cd "$$dir"; go build $(FLAGS)) \
done done
test/run.sh cmd/khepri/khepri cmd/dirdiff/dirdiff test/run.sh cmd/restic/restic cmd/dirdiff/dirdiff
clean: clean:
go clean go clean

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"errors" "errors"
@ -9,9 +9,9 @@ import (
"sync" "sync"
"time" "time"
"github.com/fd0/khepri/backend"
"github.com/fd0/khepri/chunker"
"github.com/juju/arrar" "github.com/juju/arrar"
"github.com/restic/restic/backend"
"github.com/restic/restic/chunker"
) )
const ( const (

View File

@ -1,4 +1,4 @@
package khepri_test package restic_test
import ( import (
"bytes" "bytes"
@ -6,8 +6,8 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/chunker" "github.com/restic/restic/chunker"
) )
func get_random(seed, count int) []byte { func get_random(seed, count int) []byte {
@ -48,7 +48,7 @@ func BenchmarkChunkEncrypt(b *testing.B) {
ok(b, err) ok(b, err)
buf := make([]byte, khepri.CiphertextExtension+chunker.MaxSize) buf := make([]byte, restic.CiphertextExtension+chunker.MaxSize)
_, err = key.Encrypt(buf, chunk_data.Data) _, err = key.Encrypt(buf, chunk_data.Data)
ok(b, err) ok(b, err)
} }

View File

@ -1,2 +1,2 @@
// Package backend provides local and remote storage for khepri backups. // Package backend provides local and remote storage for restic backups.
package backend package backend

View File

@ -7,7 +7,7 @@ import (
"runtime" "runtime"
"testing" "testing"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
// assert fails the test if the condition is false. // assert fails the test if the condition is false.

View File

@ -8,7 +8,7 @@ import (
"sort" "sort"
"testing" "testing"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
var testCleanup = flag.Bool("test.cleanup", true, "clean up after running tests (remove local backend directory with all content)") var testCleanup = flag.Bool("test.cleanup", true, "clean up after running tests (remove local backend directory with all content)")
@ -24,7 +24,7 @@ var TestStrings = []struct {
} }
func setupBackend(t *testing.T) *backend.Local { func setupBackend(t *testing.T) *backend.Local {
tempdir, err := ioutil.TempDir("", "khepri-test-") tempdir, err := ioutil.TempDir("", "restic-test-")
ok(t, err) ok(t, err)
b, err := backend.CreateLocal(tempdir) b, err := backend.CreateLocal(tempdir)
@ -122,9 +122,9 @@ func testBackend(b backend.Server, t *testing.T) {
func TestBackend(t *testing.T) { func TestBackend(t *testing.T) {
// test for non-existing backend // test for non-existing backend
b, err := backend.OpenLocal("/invalid-khepri-test") b, err := backend.OpenLocal("/invalid-restic-test")
assert(t, err != nil, "opening invalid repository at /invalid-khepri-test should have failed, but err is nil") assert(t, err != nil, "opening invalid repository at /invalid-restic-test should have failed, but err is nil")
assert(t, b == nil, fmt.Sprintf("opening invalid repository at /invalid-khepri-test should have failed, but b is not nil: %v", b)) assert(t, b == nil, fmt.Sprintf("opening invalid repository at /invalid-restic-test should have failed, but b is not nil: %v", b))
b = setupBackend(t) b = setupBackend(t)
defer teardownBackend(t, b) defer teardownBackend(t, b)

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"bytes" "bytes"
@ -7,7 +7,7 @@ import (
"sort" "sort"
"sync" "sync"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
type BlobList struct { type BlobList struct {

View File

@ -1,4 +1,4 @@
package khepri_test package restic_test
import ( import (
"crypto/rand" "crypto/rand"
@ -10,8 +10,8 @@ import (
"testing" "testing"
"time" "time"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
var maxWorkers = flag.Uint("workers", 100, "number of workers to test BlobList concurrent access against") var maxWorkers = flag.Uint("workers", 100, "number of workers to test BlobList concurrent access against")
@ -25,13 +25,13 @@ func randomID() []byte {
return buf return buf
} }
func newBlob() khepri.Blob { func newBlob() restic.Blob {
return khepri.Blob{ID: randomID(), Size: uint64(mrand.Uint32())} return restic.Blob{ID: randomID(), Size: uint64(mrand.Uint32())}
} }
// Test basic functionality // Test basic functionality
func TestBlobList(t *testing.T) { func TestBlobList(t *testing.T) {
bl := khepri.NewBlobList() bl := restic.NewBlobList()
b := newBlob() b := newBlob()
bl.Insert(b) bl.Insert(b)
@ -40,17 +40,17 @@ func TestBlobList(t *testing.T) {
bl.Insert(newBlob()) bl.Insert(newBlob())
} }
b2, err := bl.Find(khepri.Blob{ID: b.ID}) b2, err := bl.Find(restic.Blob{ID: b.ID})
ok(t, err) ok(t, err)
assert(t, b2.Compare(b) == 0, "items are not equal: want %v, got %v", b, b2) assert(t, b2.Compare(b) == 0, "items are not equal: want %v, got %v", b, b2)
bl2 := khepri.NewBlobList() bl2 := restic.NewBlobList()
for i := 0; i < 1000; i++ { for i := 0; i < 1000; i++ {
bl.Insert(newBlob()) bl.Insert(newBlob())
} }
b2, err = bl2.Find(b) b2, err = bl2.Find(b)
assert(t, err != nil, "found ID in khepri that was never inserted: %v", b2) assert(t, err != nil, "found ID in restic that was never inserted: %v", b2)
bl2.Merge(bl) bl2.Merge(bl)
@ -67,8 +67,8 @@ func TestBlobList(t *testing.T) {
// Test JSON encode/decode // Test JSON encode/decode
func TestBlobListJSON(t *testing.T) { func TestBlobListJSON(t *testing.T) {
bl := khepri.NewBlobList() bl := restic.NewBlobList()
b := khepri.Blob{ID: randomID()} b := restic.Blob{ID: randomID()}
bl.Insert(b) bl.Insert(b)
b2, err := bl.Find(b) b2, err := bl.Find(b)
@ -78,7 +78,7 @@ func TestBlobListJSON(t *testing.T) {
buf, err := json.Marshal(bl) buf, err := json.Marshal(bl)
ok(t, err) ok(t, err)
bl2 := khepri.BlobList{} bl2 := restic.BlobList{}
json.Unmarshal(buf, &bl2) json.Unmarshal(buf, &bl2)
b2, err = bl2.Find(b) b2, err = bl2.Find(b)
@ -93,7 +93,7 @@ func TestBlobListJSON(t *testing.T) {
func TestBlobListRandom(t *testing.T) { func TestBlobListRandom(t *testing.T) {
var wg sync.WaitGroup var wg sync.WaitGroup
worker := func(bl *khepri.BlobList) { worker := func(bl *restic.BlobList) {
defer wg.Done() defer wg.Done()
b := newBlob() b := newBlob()
@ -117,7 +117,7 @@ func TestBlobListRandom(t *testing.T) {
} }
} }
bl2 := khepri.NewBlobList() bl2 := restic.NewBlobList()
for i := 0; i < 200; i++ { for i := 0; i < 200; i++ {
bl2.Insert(newBlob()) bl2.Insert(newBlob())
} }
@ -125,7 +125,7 @@ func TestBlobListRandom(t *testing.T) {
bl2.Merge(bl) bl2.Merge(bl)
} }
bl := khepri.NewBlobList() bl := restic.NewBlobList()
for i := 0; uint(i) < *maxWorkers; i++ { for i := 0; uint(i) < *maxWorkers; i++ {
wg.Add(1) wg.Add(1)

View File

@ -6,7 +6,7 @@ import (
"math/rand" "math/rand"
"testing" "testing"
"github.com/fd0/khepri/chunker" "github.com/restic/restic/chunker"
) )
type chunk struct { type chunk struct {

View File

@ -9,13 +9,13 @@ TAGS =
# include config file if it exists # include config file if it exists
-include $(CURDIR)/config.mk -include $(CURDIR)/config.mk
all: khepri all: restic
khepri: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go) restic: $(wildcard *.go) $(wildcard ../../*.go) $(wildcard ../../*/*.go)
go build $(TAGS) -ldflags "$(LDFLAGS)" go build $(TAGS) -ldflags "$(LDFLAGS)"
debug: TAGS=-tags debug_cmd debug: TAGS=-tags debug_cmd
debug: khepri debug: restic
clean: clean:
go clean go clean

View File

@ -7,8 +7,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
) )
@ -45,7 +45,7 @@ func format_duration(sec uint64) string {
return fmt.Sprintf("%d:%02d", min, sec) return fmt.Sprintf("%d:%02d", min, sec)
} }
func print_tree2(indent int, t *khepri.Tree) { func print_tree2(indent int, t *restic.Tree) {
for _, node := range *t { for _, node := range *t {
if node.Tree != nil { if node.Tree != nil {
fmt.Printf("%s%s/\n", strings.Repeat(" ", indent), node.Name) fmt.Printf("%s%s/\n", strings.Repeat(" ", indent), node.Name)
@ -56,7 +56,7 @@ func print_tree2(indent int, t *khepri.Tree) {
} }
} }
func commandBackup(be backend.Server, key *khepri.Key, args []string) error { func commandBackup(be backend.Server, key *restic.Key, args []string) error {
if len(args) < 1 || len(args) > 2 { if len(args) < 1 || len(args) > 2 {
return errors.New("usage: backup [dir|file] [snapshot-id]") return errors.New("usage: backup [dir|file] [snapshot-id]")
} }
@ -74,7 +74,7 @@ func commandBackup(be backend.Server, key *khepri.Key, args []string) error {
fmt.Printf("found parent snapshot %v\n", parentSnapshotID) fmt.Printf("found parent snapshot %v\n", parentSnapshotID)
} }
arch, err := khepri.NewArchiver(be, key) arch, err := restic.NewArchiver(be, key)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "err: %v\n", err) fmt.Fprintf(os.Stderr, "err: %v\n", err)
} }
@ -87,10 +87,10 @@ func commandBackup(be backend.Server, key *khepri.Key, args []string) error {
fmt.Printf("scanning %s\n", target) fmt.Printf("scanning %s\n", target)
if terminal.IsTerminal(int(os.Stdout.Fd())) { if terminal.IsTerminal(int(os.Stdout.Fd())) {
ch := make(chan khepri.Stats, 20) ch := make(chan restic.Stats, 20)
arch.ScannerStats = ch arch.ScannerStats = ch
go func(ch <-chan khepri.Stats) { go func(ch <-chan restic.Stats) {
for stats := range ch { for stats := range ch {
fmt.Printf("\r%6d directories, %6d files, %14s", stats.Directories, stats.Files, format_bytes(stats.Bytes)) fmt.Printf("\r%6d directories, %6d files, %14s", stats.Directories, stats.Files, format_bytes(stats.Bytes))
} }
@ -112,16 +112,16 @@ func commandBackup(be backend.Server, key *khepri.Key, args []string) error {
fmt.Printf("\r%6d directories, %6d files, %14s\n", arch.Stats.Directories, arch.Stats.Files, format_bytes(arch.Stats.Bytes)) fmt.Printf("\r%6d directories, %6d files, %14s\n", arch.Stats.Directories, arch.Stats.Files, format_bytes(arch.Stats.Bytes))
stats := khepri.Stats{} stats := restic.Stats{}
start := time.Now() start := time.Now()
if terminal.IsTerminal(int(os.Stdout.Fd())) { if terminal.IsTerminal(int(os.Stdout.Fd())) {
ch := make(chan khepri.Stats, 20) ch := make(chan restic.Stats, 20)
arch.SaveStats = ch arch.SaveStats = ch
ticker := time.NewTicker(time.Second) ticker := time.NewTicker(time.Second)
var eta, bps uint64 var eta, bps uint64
go func(ch <-chan khepri.Stats) { go func(ch <-chan restic.Stats) {
status := func(sec uint64) { status := func(sec uint64) {
fmt.Printf("\x1b[2K\r[%s] %3.2f%% %s/s %s / %s ETA %s", fmt.Printf("\x1b[2K\r[%s] %3.2f%% %s/s %s / %s ETA %s",

View File

@ -6,15 +6,15 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["cat"] = commandCat commands["cat"] = commandCat
} }
func commandCat(be backend.Server, key *khepri.Key, args []string) error { func commandCat(be backend.Server, key *restic.Key, args []string) error {
if len(args) != 2 { if len(args) != 2 {
return errors.New("usage: cat [blob|tree|snapshot|key|lock] ID") return errors.New("usage: cat [blob|tree|snapshot|key|lock] ID")
} }
@ -36,7 +36,7 @@ func commandCat(be backend.Server, key *khepri.Key, args []string) error {
} }
} }
ch, err := khepri.NewContentHandler(be, key) ch, err := restic.NewContentHandler(be, key)
if err != nil { if err != nil {
return err return err
} }
@ -71,7 +71,7 @@ func commandCat(be backend.Server, key *khepri.Key, args []string) error {
return err return err
case "tree": case "tree":
var tree khepri.Tree var tree restic.Tree
// try id // try id
err := ch.LoadJSON(backend.Tree, id, &tree) err := ch.LoadJSON(backend.Tree, id, &tree)
if err != nil { if err != nil {
@ -103,7 +103,7 @@ func commandCat(be backend.Server, key *khepri.Key, args []string) error {
return nil return nil
case "map": case "map":
var bl khepri.BlobList var bl restic.BlobList
err := ch.LoadJSONRaw(backend.Map, id, &bl) err := ch.LoadJSONRaw(backend.Map, id, &bl)
if err != nil { if err != nil {
return err return err
@ -118,7 +118,7 @@ func commandCat(be backend.Server, key *khepri.Key, args []string) error {
return nil return nil
case "snapshot": case "snapshot":
var sn khepri.Snapshot var sn restic.Snapshot
err = ch.LoadJSONRaw(backend.Snapshot, id, &sn) err = ch.LoadJSONRaw(backend.Snapshot, id, &sn)
if err != nil { if err != nil {
@ -139,7 +139,7 @@ func commandCat(be backend.Server, key *khepri.Key, args []string) error {
return err return err
} }
var key khepri.Key var key restic.Key
err = json.Unmarshal(data, &key) err = json.Unmarshal(data, &key)
if err != nil { if err != nil {
return err return err

View File

@ -4,15 +4,15 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["fsck"] = commandFsck commands["fsck"] = commandFsck
} }
func fsckFile(ch *khepri.ContentHandler, IDs []backend.ID) error { func fsckFile(ch *restic.ContentHandler, IDs []backend.ID) error {
for _, id := range IDs { for _, id := range IDs {
debug("checking data blob %v\n", id) debug("checking data blob %v\n", id)
@ -26,10 +26,10 @@ func fsckFile(ch *khepri.ContentHandler, IDs []backend.ID) error {
return nil return nil
} }
func fsckTree(ch *khepri.ContentHandler, id backend.ID) error { func fsckTree(ch *restic.ContentHandler, id backend.ID) error {
debug("checking tree %v\n", id) debug("checking tree %v\n", id)
tree, err := khepri.LoadTree(ch, id) tree, err := restic.LoadTree(ch, id)
if err != nil { if err != nil {
return err return err
} }
@ -68,10 +68,10 @@ func fsckTree(ch *khepri.ContentHandler, id backend.ID) error {
return nil return nil
} }
func fsck_snapshot(be backend.Server, key *khepri.Key, id backend.ID) error { func fsck_snapshot(be backend.Server, key *restic.Key, id backend.ID) error {
debug("checking snapshot %v\n", id) debug("checking snapshot %v\n", id)
ch, err := khepri.NewContentHandler(be, key) ch, err := restic.NewContentHandler(be, key)
if err != nil { if err != nil {
return err return err
} }
@ -92,7 +92,7 @@ func fsck_snapshot(be backend.Server, key *khepri.Key, id backend.ID) error {
return fsckTree(ch, sn.Content) return fsckTree(ch, sn.Content)
} }
func commandFsck(be backend.Server, key *khepri.Key, args []string) error { func commandFsck(be backend.Server, key *restic.Key, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errors.New("usage: fsck [all|snapshot-id]") return errors.New("usage: fsck [all|snapshot-id]")
} }

View File

@ -6,15 +6,15 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["key"] = commandKey commands["key"] = commandKey
} }
func list_keys(be backend.Server, key *khepri.Key) error { func list_keys(be backend.Server, key *restic.Key) error {
tab := NewTable() tab := NewTable()
tab.Header = fmt.Sprintf(" %-10s %-10s %-10s %s", "ID", "User", "Host", "Created") tab.Header = fmt.Sprintf(" %-10s %-10s %-10s %s", "ID", "User", "Host", "Created")
tab.RowFormat = "%s%-10s %-10s %-10s %s" tab.RowFormat = "%s%-10s %-10s %-10s %s"
@ -25,7 +25,7 @@ func list_keys(be backend.Server, key *khepri.Key) error {
} }
backend.Each(be, backend.Key, func(id backend.ID, data []byte, err error) { backend.Each(be, backend.Key, func(id backend.ID, data []byte, err error) {
k := khepri.Key{} k := restic.Key{}
err = json.Unmarshal(data, &k) err = json.Unmarshal(data, &k)
if err != nil { if err != nil {
return return
@ -46,9 +46,9 @@ func list_keys(be backend.Server, key *khepri.Key) error {
return nil return nil
} }
func add_key(be backend.Server, key *khepri.Key) error { func add_key(be backend.Server, key *restic.Key) error {
pw := readPassword("KHEPRI_NEWPASSWORD", "enter password for new key: ") pw := readPassword("RESTIC_NEWPASSWORD", "enter password for new key: ")
pw2 := readPassword("KHEPRI_NEWPASSWORD", "enter password again: ") pw2 := readPassword("RESTIC_NEWPASSWORD", "enter password again: ")
if pw != pw2 { if pw != pw2 {
return errors.New("passwords do not match") return errors.New("passwords do not match")
@ -64,7 +64,7 @@ func add_key(be backend.Server, key *khepri.Key) error {
return nil return nil
} }
func delete_key(be backend.Server, key *khepri.Key, id backend.ID) error { func delete_key(be backend.Server, key *restic.Key, id backend.ID) error {
if id.Equal(key.ID()) { if id.Equal(key.ID()) {
return errors.New("refusing to remove key currently used to access repository") return errors.New("refusing to remove key currently used to access repository")
} }
@ -78,9 +78,9 @@ func delete_key(be backend.Server, key *khepri.Key, id backend.ID) error {
return nil return nil
} }
func change_password(be backend.Server, key *khepri.Key) error { func change_password(be backend.Server, key *restic.Key) error {
pw := readPassword("KHEPRI_NEWPASSWORD", "enter password for new key: ") pw := readPassword("RESTIC_NEWPASSWORD", "enter password for new key: ")
pw2 := readPassword("KHEPRI_NEWPASSWORD", "enter password again: ") pw2 := readPassword("RESTIC_NEWPASSWORD", "enter password again: ")
if pw != pw2 { if pw != pw2 {
return errors.New("passwords do not match") return errors.New("passwords do not match")
@ -103,7 +103,7 @@ func change_password(be backend.Server, key *khepri.Key) error {
return nil return nil
} }
func commandKey(be backend.Server, key *khepri.Key, args []string) error { func commandKey(be backend.Server, key *restic.Key, args []string) error {
if len(args) < 1 || (args[0] == "rm" && len(args) != 2) { if len(args) < 1 || (args[0] == "rm" && len(args) != 2) {
return errors.New("usage: key [list|add|rm|change] [ID]") return errors.New("usage: key [list|add|rm|change] [ID]")
} }

View File

@ -4,15 +4,15 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["list"] = commandList commands["list"] = commandList
} }
func commandList(be backend.Server, key *khepri.Key, args []string) error { func commandList(be backend.Server, key *restic.Key, args []string) error {
if len(args) != 1 { if len(args) != 1 {
return errors.New("usage: list [data|trees|snapshots|keys|locks]") return errors.New("usage: list [data|trees|snapshots|keys|locks]")
} }

View File

@ -6,15 +6,15 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["ls"] = commandLs commands["ls"] = commandLs
} }
func print_node(prefix string, n *khepri.Node) string { func print_node(prefix string, n *restic.Node) string {
switch n.Type { switch n.Type {
case "file": case "file":
return fmt.Sprintf("%s %5d %5d %6d %s %s", return fmt.Sprintf("%s %5d %5d %6d %s %s",
@ -30,8 +30,8 @@ func print_node(prefix string, n *khepri.Node) string {
} }
} }
func print_tree(prefix string, ch *khepri.ContentHandler, id backend.ID) error { func print_tree(prefix string, ch *restic.ContentHandler, id backend.ID) error {
tree := &khepri.Tree{} tree := &restic.Tree{}
err := ch.LoadJSON(backend.Tree, id, tree) err := ch.LoadJSON(backend.Tree, id, tree)
if err != nil { if err != nil {
@ -52,7 +52,7 @@ func print_tree(prefix string, ch *khepri.ContentHandler, id backend.ID) error {
return nil return nil
} }
func commandLs(be backend.Server, key *khepri.Key, args []string) error { func commandLs(be backend.Server, key *restic.Key, args []string) error {
if len(args) < 1 || len(args) > 2 { if len(args) < 1 || len(args) > 2 {
return errors.New("usage: ls SNAPSHOT_ID [dir]") return errors.New("usage: ls SNAPSHOT_ID [dir]")
} }
@ -62,7 +62,7 @@ func commandLs(be backend.Server, key *khepri.Key, args []string) error {
return err return err
} }
ch, err := khepri.NewContentHandler(be, key) ch, err := restic.NewContentHandler(be, key)
if err != nil { if err != nil {
return err return err
} }

View File

@ -5,15 +5,15 @@ import (
"fmt" "fmt"
"os" "os"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func init() { func init() {
commands["restore"] = commandRestore commands["restore"] = commandRestore
} }
func commandRestore(be backend.Server, key *khepri.Key, args []string) error { func commandRestore(be backend.Server, key *restic.Key, args []string) error {
if len(args) != 2 { if len(args) != 2 {
return errors.New("usage: restore ID dir") return errors.New("usage: restore ID dir")
} }
@ -26,13 +26,13 @@ func commandRestore(be backend.Server, key *khepri.Key, args []string) error {
target := args[1] target := args[1]
// create restorer // create restorer
res, err := khepri.NewRestorer(be, key, id) res, err := restic.NewRestorer(be, key, id)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "creating restorer failed: %v\n", err) fmt.Fprintf(os.Stderr, "creating restorer failed: %v\n", err)
os.Exit(2) os.Exit(2)
} }
res.Error = func(dir string, node *khepri.Node, err error) error { res.Error = func(dir string, node *restic.Node, err error) error {
fmt.Fprintf(os.Stderr, "error for %s: %+v\n", dir, err) fmt.Fprintf(os.Stderr, "error for %s: %+v\n", dir, err)
// if node.Type == "dir" { // if node.Type == "dir" {

View File

@ -9,8 +9,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
const ( const (
@ -76,12 +76,12 @@ func init() {
commands["snapshots"] = commandSnapshots commands["snapshots"] = commandSnapshots
} }
func commandSnapshots(be backend.Server, key *khepri.Key, args []string) error { func commandSnapshots(be backend.Server, key *restic.Key, args []string) error {
if len(args) != 0 { if len(args) != 0 {
return errors.New("usage: snapshots") return errors.New("usage: snapshots")
} }
ch, err := khepri.NewContentHandler(be, key) ch, err := restic.NewContentHandler(be, key)
if err != nil { if err != nil {
return err return err
} }
@ -90,7 +90,7 @@ func commandSnapshots(be backend.Server, key *khepri.Key, args []string) error {
tab.Header = fmt.Sprintf("%-8s %-19s %-10s %s", "ID", "Date", "Source", "Directory") tab.Header = fmt.Sprintf("%-8s %-19s %-10s %s", "ID", "Date", "Source", "Directory")
tab.RowFormat = "%-8s %-19s %-10s %s" tab.RowFormat = "%-8s %-19s %-10s %s"
list := []*khepri.Snapshot{} list := []*restic.Snapshot{}
backend.EachID(be, backend.Snapshot, func(id backend.ID) { backend.EachID(be, backend.Snapshot, func(id backend.ID) {
sn, err := ch.LoadSnapshot(id) sn, err := ch.LoadSnapshot(id)
if err != nil { if err != nil {

View File

@ -15,7 +15,7 @@ var debugLogger = initDebugLogger()
func initDebugLogger() *log.Logger { func initDebugLogger() *log.Logger {
// create new log file // create new log file
filename := fmt.Sprintf("khepri-debug-%d-%s", filename := fmt.Sprintf("restic-debug-%d-%s",
os.Getpid(), time.Now().Format("20060201-150405")) os.Getpid(), time.Now().Format("20060201-150405"))
path := filepath.Join(os.TempDir(), filename) path := filepath.Join(os.TempDir(), filename)
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
@ -26,8 +26,8 @@ func initDebugLogger() *log.Logger {
// open logger // open logger
l := log.New(io.MultiWriter(os.Stderr, f), "DEBUG: ", log.LstdFlags) l := log.New(io.MultiWriter(os.Stderr, f), "DEBUG: ", log.LstdFlags)
fmt.Fprintf(os.Stderr, "debug log for khepri command activated, writing log file %s\n", path) fmt.Fprintf(os.Stderr, "debug log for restic command activated, writing log file %s\n", path)
l.Printf("khepri %s", version) l.Printf("restic %s", version)
return l return l
} }

BIN
cmd/restic/khepri Executable file

Binary file not shown.

View File

@ -11,9 +11,9 @@ import (
"golang.org/x/crypto/ssh/terminal" "golang.org/x/crypto/ssh/terminal"
"github.com/fd0/khepri"
"github.com/fd0/khepri/backend"
"github.com/jessevdk/go-flags" "github.com/jessevdk/go-flags"
"github.com/restic/restic"
"github.com/restic/restic/backend"
) )
var version = "compiled manually" var version = "compiled manually"
@ -30,7 +30,7 @@ func errx(code int, format string, data ...interface{}) {
os.Exit(code) os.Exit(code)
} }
type commandFunc func(backend.Server, *khepri.Key, []string) error type commandFunc func(backend.Server, *restic.Key, []string) error
var commands = make(map[string]commandFunc) var commands = make(map[string]commandFunc)
@ -55,8 +55,8 @@ func readPassword(env string, prompt string) string {
} }
func commandInit(repo string) error { func commandInit(repo string) error {
pw := readPassword("KHEPRI_PASSWORD", "enter password for new backend: ") pw := readPassword("RESTIC_PASSWORD", "enter password for new backend: ")
pw2 := readPassword("KHEPRI_PASSWORD", "enter password again: ") pw2 := readPassword("RESTIC_PASSWORD", "enter password again: ")
if pw != pw2 { if pw != pw2 {
errx(1, "passwords do not match") errx(1, "passwords do not match")
@ -68,13 +68,13 @@ func commandInit(repo string) error {
os.Exit(1) os.Exit(1)
} }
_, err = khepri.CreateKey(be, pw) _, err = restic.CreateKey(be, pw)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "creating key in backend at %s failed: %v\n", repo, err) fmt.Fprintf(os.Stderr, "creating key in backend at %s failed: %v\n", repo, err)
os.Exit(1) os.Exit(1)
} }
fmt.Printf("created khepri backend at %s\n", be.Location()) fmt.Printf("created restic backend at %s\n", be.Location())
return nil return nil
} }
@ -135,7 +135,7 @@ func main() {
log.SetOutput(os.Stdout) log.SetOutput(os.Stdout)
opts.Repo = os.Getenv("KHEPRI_REPOSITORY") opts.Repo = os.Getenv("RESTIC_REPOSITORY")
args, err := flags.Parse(&opts) args, err := flags.Parse(&opts)
if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp { if e, ok := err.(*flags.Error); ok && e.Type == flags.ErrHelp {
@ -143,7 +143,7 @@ func main() {
} }
if opts.Repo == "" { if opts.Repo == "" {
fmt.Fprintf(os.Stderr, "no repository specified, use -r or KHEPRI_REPOSITORY variable\n") fmt.Fprintf(os.Stderr, "no repository specified, use -r or RESTIC_REPOSITORY variable\n")
os.Exit(1) os.Exit(1)
} }
@ -183,7 +183,7 @@ func main() {
errx(1, "unable to open repo: %v", err) errx(1, "unable to open repo: %v", err)
} }
key, err := khepri.SearchKey(repo, readPassword("KHEPRI_PASSWORD", "Enter Password for Repository: ")) key, err := restic.SearchKey(repo, readPassword("RESTIC_PASSWORD", "Enter Password for Repository: "))
if err != nil { if err != nil {
errx(2, "unable to open repo: %v", err) errx(2, "unable to open repo: %v", err)
} }
@ -193,5 +193,5 @@ func main() {
errx(1, "error executing command %q: %v", cmd, err) errx(1, "error executing command %q: %v", cmd, err)
} }
khepri.PoolAlloc() restic.PoolAlloc()
} }

View File

@ -1,11 +1,11 @@
package khepri package restic
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
var ErrWrongData = errors.New("wrong data decrypt, checksum does not match") var ErrWrongData = errors.New("wrong data decrypt, checksum does not match")

View File

@ -1,6 +1,6 @@
// +build debug // +build debug
package khepri package restic
import ( import (
"fmt" "fmt"
@ -15,7 +15,7 @@ var debugLogger = initDebugLogger()
func initDebugLogger() *log.Logger { func initDebugLogger() *log.Logger {
// create new log file // create new log file
filename := fmt.Sprintf("khepri-lib-debug-%d-%s", filename := fmt.Sprintf("restic-lib-debug-%d-%s",
os.Getpid(), time.Now().Format("20060201-150405")) os.Getpid(), time.Now().Format("20060201-150405"))
path := filepath.Join(os.TempDir(), filename) path := filepath.Join(os.TempDir(), filename)
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600) f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0600)
@ -26,7 +26,7 @@ func initDebugLogger() *log.Logger {
// open logger // open logger
l := log.New(io.MultiWriter(os.Stderr, f), "DEBUG: ", log.LstdFlags) l := log.New(io.MultiWriter(os.Stderr, f), "DEBUG: ", log.LstdFlags)
fmt.Fprintf(os.Stderr, "debug log for khepri library activated, writing log file %s\n", path) fmt.Fprintf(os.Stderr, "debug log for restic library activated, writing log file %s\n", path)
return l return l
} }

View File

@ -1,5 +1,5 @@
// +build !debug // +build !debug
package khepri package restic
func debug(fmt string, args ...interface{}) {} func debug(fmt string, args ...interface{}) {}

View File

@ -1,4 +1,4 @@
package khepri_test package restic_test
import ( import (
"fmt" "fmt"

6
key.go
View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"crypto/aes" "crypto/aes"
@ -14,8 +14,8 @@ import (
"os/user" "os/user"
"time" "time"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
"github.com/fd0/khepri/chunker" "github.com/restic/restic/chunker"
"golang.org/x/crypto/scrypt" "golang.org/x/crypto/scrypt"
) )

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"bytes" "bytes"

View File

@ -1,4 +1,4 @@
package khepri_test package restic_test
import ( import (
"flag" "flag"
@ -7,16 +7,16 @@ import (
"os" "os"
"testing" "testing"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
"github.com/fd0/khepri/chunker" "github.com/restic/restic/chunker"
) )
var testPassword = "foobar" var testPassword = "foobar"
var testCleanup = flag.Bool("test.cleanup", true, "clean up after running tests (remove local backend directory with all content)") var testCleanup = flag.Bool("test.cleanup", true, "clean up after running tests (remove local backend directory with all content)")
func setupBackend(t testing.TB) *backend.Local { func setupBackend(t testing.TB) *backend.Local {
tempdir, err := ioutil.TempDir("", "khepri-test-") tempdir, err := ioutil.TempDir("", "restic-test-")
ok(t, err) ok(t, err)
b, err := backend.CreateLocal(tempdir) b, err := backend.CreateLocal(tempdir)
@ -34,8 +34,8 @@ func teardownBackend(t testing.TB, b *backend.Local) {
ok(t, os.RemoveAll(b.Location())) ok(t, os.RemoveAll(b.Location()))
} }
func setupKey(t testing.TB, be backend.Server, password string) *khepri.Key { func setupKey(t testing.TB, be backend.Server, password string) *restic.Key {
k, err := khepri.CreateKey(be, password) k, err := restic.CreateKey(be, password)
ok(t, err) ok(t, err)
return k return k
@ -60,14 +60,14 @@ func TestEncryptDecrypt(t *testing.T) {
_, err = io.ReadFull(f, data) _, err = io.ReadFull(f, data)
ok(t, err) ok(t, err)
ciphertext := khepri.GetChunkBuf("TestEncryptDecrypt") ciphertext := restic.GetChunkBuf("TestEncryptDecrypt")
n, err := k.Encrypt(ciphertext, data) n, err := k.Encrypt(ciphertext, data)
ok(t, err) ok(t, err)
plaintext, err := k.Decrypt(ciphertext[:n]) plaintext, err := k.Decrypt(ciphertext[:n])
ok(t, err) ok(t, err)
khepri.FreeChunkBuf("TestEncryptDecrypt", ciphertext) restic.FreeChunkBuf("TestEncryptDecrypt", ciphertext)
equals(t, plaintext, data) equals(t, plaintext, data)
} }
@ -86,7 +86,7 @@ func TestLargeEncrypt(t *testing.T) {
_, err = io.ReadFull(f, data) _, err = io.ReadFull(f, data)
ok(t, err) ok(t, err)
ciphertext := make([]byte, size+khepri.CiphertextExtension) ciphertext := make([]byte, size+restic.CiphertextExtension)
n, err := k.Encrypt(ciphertext, data) n, err := k.Encrypt(ciphertext, data)
ok(t, err) ok(t, err)
@ -108,12 +108,12 @@ func BenchmarkEncrypt(b *testing.B) {
b.ResetTimer() b.ResetTimer()
b.SetBytes(int64(size)) b.SetBytes(int64(size))
buf := khepri.GetChunkBuf("BenchmarkEncrypt") buf := restic.GetChunkBuf("BenchmarkEncrypt")
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
_, err := k.Encrypt(buf, data) _, err := k.Encrypt(buf, data)
ok(b, err) ok(b, err)
} }
khepri.FreeChunkBuf("BenchmarkEncrypt", buf) restic.FreeChunkBuf("BenchmarkEncrypt", buf)
} }
func BenchmarkDecrypt(b *testing.B) { func BenchmarkDecrypt(b *testing.B) {
@ -124,7 +124,7 @@ func BenchmarkDecrypt(b *testing.B) {
defer teardownBackend(b, be) defer teardownBackend(b, be)
k := setupKey(b, be, testPassword) k := setupKey(b, be, testPassword)
ciphertext := khepri.GetChunkBuf("BenchmarkDecrypt") ciphertext := restic.GetChunkBuf("BenchmarkDecrypt")
n, err := k.Encrypt(ciphertext, data) n, err := k.Encrypt(ciphertext, data)
ok(b, err) ok(b, err)
@ -135,5 +135,5 @@ func BenchmarkDecrypt(b *testing.B) {
_, err := k.Decrypt(ciphertext[:n]) _, err := k.Decrypt(ciphertext[:n])
ok(b, err) ok(b, err)
} }
khepri.FreeChunkBuf("BenchmarkDecrypt", ciphertext) restic.FreeChunkBuf("BenchmarkDecrypt", ciphertext)
} }

View File

@ -1,4 +1,4 @@
package khepri package restic
import "sync" import "sync"

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"errors" "errors"
@ -6,8 +6,8 @@ import (
"os" "os"
"path/filepath" "path/filepath"
"github.com/fd0/khepri/backend"
"github.com/juju/arrar" "github.com/juju/arrar"
"github.com/restic/restic/backend"
) )
type Restorer struct { type Restorer struct {

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"fmt" "fmt"
@ -7,7 +7,7 @@ import (
"path/filepath" "path/filepath"
"time" "time"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
type Snapshot struct { type Snapshot struct {

View File

@ -1,16 +1,16 @@
package khepri_test package restic_test
import ( import (
"testing" "testing"
"time" "time"
"github.com/fd0/khepri" "github.com/restic/restic"
"github.com/fd0/khepri/backend" "github.com/restic/restic/backend"
) )
func testSnapshot(t *testing.T, be backend.Server) { func testSnapshot(t *testing.T, be backend.Server) {
var err error var err error
sn := khepri.NewSnapshot("/home/foobar") sn := restic.NewSnapshot("/home/foobar")
sn.Content, err = backend.ParseID("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2") sn.Content, err = backend.ParseID("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2")
ok(t, err) ok(t, err)
sn.Time, err = time.Parse(time.RFC3339Nano, "2014-08-03T17:49:05.378595539+02:00") sn.Time, err = time.Parse(time.RFC3339Nano, "2014-08-03T17:49:05.378595539+02:00")

View File

@ -2,17 +2,17 @@
set -e set -e
export khepri="${1:-khepri}"; shift export restic="${1:-restic}"; shift
export dirdiff="${1:-dirdiff}"; shift export dirdiff="${1:-dirdiff}"; shift
export dir=$(dirname "$0") export dir=$(dirname "$0")
export fake_data_file="${dir}/fake-data.tar.gz" export fake_data_file="${dir}/fake-data.tar.gz"
prepare() { prepare() {
export BASE="$(mktemp --tmpdir --directory khepri-testsuite-XXXXXX)" export BASE="$(mktemp --tmpdir --directory restic-testsuite-XXXXXX)"
export KHEPRI_REPOSITORY="${BASE}/khepri-backup" export RESTIC_REPOSITORY="${BASE}/restic-backup"
export DATADIR="${BASE}/fake-data" export DATADIR="${BASE}/fake-data"
export KHEPRI_PASSWORD="foobar" export RESTIC_PASSWORD="foobar"
debug "repository is at ${KHEPRI_REPOSITORY}" debug "repository is at ${RESTIC_REPOSITORY}"
mkdir -p "$DATADIR" mkdir -p "$DATADIR"
(cd "$DATADIR"; tar xz) < "$fake_data_file" (cd "$DATADIR"; tar xz) < "$fake_data_file"
@ -28,11 +28,11 @@ cleanup() {
rm -rf "${BASE}" rm -rf "${BASE}"
debug "removed dir ${BASE}" debug "removed dir ${BASE}"
unset BASE unset BASE
unset KHEPRI_REPOSITORY unset RESTIC_REPOSITORY
} }
khepri() { restic() {
"${khepri}" "$@" "${restic}" "$@"
} }
dirdiff() { dirdiff() {
@ -70,10 +70,10 @@ run() {
fi fi
} }
export -f khepri dirdiff prepare cleanup msg debug pass err fail run export -f restic dirdiff prepare cleanup msg debug pass err fail run
if [ ! -x "$khepri" ]; then if [ ! -x "$restic" ]; then
fail khepri binary not found! fail restic binary not found!
fi fi
if [ "$#" -gt 0 ]; then if [ "$#" -gt 0 ]; then

View File

@ -1,15 +1,15 @@
set -e set -e
prepare prepare
run khepri init run restic init
run khepri backup "${BASE}/fake-data" run restic backup "${BASE}/fake-data"
run khepri restore "$(basename "$KHEPRI_REPOSITORY"/snapshots/*)" "${BASE}/fake-data-restore" run restic restore "$(basename "$RESTIC_REPOSITORY"/snapshots/*)" "${BASE}/fake-data-restore"
dirdiff "${BASE}/fake-data" "${BASE}/fake-data-restore/fake-data" dirdiff "${BASE}/fake-data" "${BASE}/fake-data-restore/fake-data"
SNAPSHOT=$(run khepri list snapshots) SNAPSHOT=$(run restic list snapshots)
run khepri backup "${BASE}/fake-data" $SNAPSHOT run restic backup "${BASE}/fake-data" $SNAPSHOT
run khepri restore "$(basename "$KHEPRI_REPOSITORY"/snapshots/*)" "${BASE}/fake-data-restore-incremental" run restic restore "$(basename "$RESTIC_REPOSITORY"/snapshots/*)" "${BASE}/fake-data-restore-incremental"
dirdiff "${BASE}/fake-data" "${BASE}/fake-data-restore-incremental/fake-data" dirdiff "${BASE}/fake-data" "${BASE}/fake-data-restore-incremental/fake-data"
run khepri fsck all run restic fsck all
cleanup cleanup

View File

@ -2,7 +2,7 @@ set -e
dump_repo() { dump_repo() {
if [ "$FAILED" == "1" ]; then if [ "$FAILED" == "1" ]; then
tar cvz "$KHEPRI_REPOSITORY" | base64 >&2 tar cvz "$RESTIC_REPOSITORY" | base64 >&2
fi fi
} }
@ -11,31 +11,31 @@ FAILED=1
trap dump_repo 0 trap dump_repo 0
prepare prepare
unset KHEPRI_PASSWORD unset RESTIC_PASSWORD
KHEPRI_PASSWORD=foo run khepri init RESTIC_PASSWORD=foo run restic init
KHEPRI_PASSWORD=foo run khepri key list RESTIC_PASSWORD=foo run restic key list
KHEPRI_PASSWORD=foo KHEPRI_NEWPASSWORD=foobar run khepri key change RESTIC_PASSWORD=foo RESTIC_NEWPASSWORD=foobar run restic key change
KHEPRI_PASSWORD=foobar run khepri key list RESTIC_PASSWORD=foobar run restic key list
KHEPRI_PASSWORD=foobar KHEPRI_NEWPASSWORD=foo run khepri key change RESTIC_PASSWORD=foobar RESTIC_NEWPASSWORD=foo run restic key change
OLD_PWD=foo OLD_PWD=foo
for i in {1..3}; do for i in {1..3}; do
NEW_PWD=bar$i NEW_PWD=bar$i
KHEPRI_PASSWORD=$OLD_PWD KHEPRI_NEWPASSWORD=$NEW_PWD run khepri key add RESTIC_PASSWORD=$OLD_PWD RESTIC_NEWPASSWORD=$NEW_PWD run restic key add
KHEPRI_PASSWORD=$OLD_PWD run khepri key list RESTIC_PASSWORD=$OLD_PWD run restic key list
KHEPRI_PASSWORD=$NEW_PWD run khepri key list RESTIC_PASSWORD=$NEW_PWD run restic key list
export KHEPRI_PASSWORD=$OLD_PWD export RESTIC_PASSWORD=$OLD_PWD
ID=$(khepri key list | grep '^\*'|cut -d ' ' -f 1| sed 's/^.//') ID=$(restic key list | grep '^\*'|cut -d ' ' -f 1| sed 's/^.//')
unset KHEPRI_PASSWORD unset RESTIC_PASSWORD
KHEPRI_PASSWORD=$NEW_PWD run khepri key rm $ID RESTIC_PASSWORD=$NEW_PWD run restic key rm $ID
KHEPRI_PASSWORD=$NEW_PWD run khepri key list RESTIC_PASSWORD=$NEW_PWD run restic key list
OLD_PWD=bar$i OLD_PWD=bar$i
done done
KHEPRI_PASSWORD=$OLD_PWD run khepri fsck all RESTIC_PASSWORD=$OLD_PWD run restic fsck all
cleanup cleanup

View File

@ -1,4 +1,4 @@
package khepri package restic
import ( import (
"errors" "errors"
@ -11,8 +11,8 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/fd0/khepri/backend"
"github.com/juju/arrar" "github.com/juju/arrar"
"github.com/restic/restic/backend"
) )
type Tree []*Node type Tree []*Node

View File

@ -1,4 +1,4 @@
package khepri_test package restic_test
import ( import (
"io/ioutil" "io/ioutil"
@ -18,7 +18,7 @@ var testFiles = []struct {
// prepareDir creates a temporary directory and returns it. // prepareDir creates a temporary directory and returns it.
func prepareDir(t *testing.T) string { func prepareDir(t *testing.T) string {
tempdir, err := ioutil.TempDir("", "khepri-test-") tempdir, err := ioutil.TempDir("", "restic-test-")
ok(t, err) ok(t, err)
for _, test := range testFiles { for _, test := range testFiles {

View File

@ -1,4 +1,4 @@
package khepri package restic
// Add constant O_PATH missing from Go1.3, will be added to Go1.4 according to // Add constant O_PATH missing from Go1.3, will be added to Go1.4 according to
// https://code.google.com/p/go/issues/detail?id=7830 // https://code.google.com/p/go/issues/detail?id=7830