From 2428843faa27c10c2279b1ed375407679730510d Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Mon, 11 Aug 2014 22:47:24 +0200 Subject: [PATCH] Refactor --- cmd/khepri/cmd_backup.go | 113 +-------- cmd/khepri/cmd_dump.go | 90 +++++++ cmd/khepri/cmd_fsck.go | 2 +- cmd/khepri/cmd_restore.go | 154 +++++++----- cmd/khepri/main.go | 1 + cmd/stat/stat.go | 37 +++ cmd/tree_serialise/main.go | 222 +++++++++++++++++ ...16f7e8649e94fb4fc21fe77e8310c060f61caaff8a | 1 + ...66eca49c67d251459787765f9c5c6af513e3db0c72 | 1 + ...2b711174c17df3156b77c14015ce633c9722c0e146 | 1 + cmd/tree_test/main.go | 69 ++++++ repository.go | 9 +- snapshot.go | 21 +- snapshot_test.go | 2 +- test/fake-data.tar.gz | Bin 177445 -> 177701 bytes tree.go | 226 ++++++++++++++++-- tree_test.go | 72 ------ zerrors_linux.go | 5 + 18 files changed, 764 insertions(+), 262 deletions(-) create mode 100644 cmd/khepri/cmd_dump.go create mode 100644 cmd/stat/stat.go create mode 100644 cmd/tree_serialise/main.go create mode 100644 cmd/tree_test/khepri-repo/blobs/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a create mode 100644 cmd/tree_test/khepri-repo/blobs/655ee6b9ff7fb7324f1e8566eca49c67d251459787765f9c5c6af513e3db0c72 create mode 100644 cmd/tree_test/khepri-repo/blobs/9e3528071fbfda7702010f2b711174c17df3156b77c14015ce633c9722c0e146 create mode 100644 cmd/tree_test/main.go delete mode 100644 tree_test.go create mode 100644 zerrors_linux.go diff --git a/cmd/khepri/cmd_backup.go b/cmd/khepri/cmd_backup.go index 1b4d80988..5a3c2f277 100644 --- a/cmd/khepri/cmd_backup.go +++ b/cmd/khepri/cmd_backup.go @@ -1,117 +1,13 @@ package main import ( - "crypto/sha256" "errors" "fmt" - "io" "log" - "os" - "path/filepath" "github.com/fd0/khepri" ) -func hash(filename string) (khepri.ID, error) { - h := sha256.New() - f, err := os.Open(filename) - if err != nil { - return nil, err - } - - io.Copy(h, f) - return h.Sum([]byte{}), nil -} - -func store_file(repo *khepri.Repository, path string) (khepri.ID, error) { - obj, idch, err := repo.Create(khepri.TYPE_BLOB) - if err != nil { - return nil, err - } - - file, err := os.Open(path) - defer func() { - file.Close() - }() - - _, err = io.Copy(obj, file) - if err != nil { - return nil, err - } - - err = obj.Close() - if err != nil { - return nil, err - } - - return <-idch, nil -} - -func archive_dir(repo *khepri.Repository, path string) (khepri.ID, error) { - log.Printf("archiving dir %q", path) - - dir, err := os.Open(path) - if err != nil { - log.Printf("open(%q): %v\n", path, err) - return nil, err - } - - entries, err := dir.Readdir(-1) - if err != nil { - log.Printf("readdir(%q): %v\n", path, err) - return nil, err - } - - // use nil ID for empty directories - if len(entries) == 0 { - return nil, nil - } - - t := khepri.NewTree() - for _, e := range entries { - node := khepri.NodeFromFileInfo(e) - - var id khepri.ID - var err error - - if e.IsDir() { - id, err = archive_dir(repo, filepath.Join(path, e.Name())) - } else { - id, err = store_file(repo, filepath.Join(path, e.Name())) - } - - node.Content = id - - t.Nodes = append(t.Nodes, node) - - if err != nil { - log.Printf(" error storing %q: %v\n", e.Name(), err) - continue - } - } - - log.Printf(" dir %q: %v entries", path, len(t.Nodes)) - - obj, idch, err := repo.Create(khepri.TYPE_BLOB) - - if err != nil { - log.Printf("error creating object for tree: %v", err) - return nil, err - } - - err = t.Save(obj) - if err != nil { - log.Printf("error saving tree to repo: %v", err) - } - - obj.Close() - - id := <-idch - log.Printf("tree for %q saved at %s", path, id) - - return id, nil -} - func commandBackup(repo *khepri.Repository, args []string) error { if len(args) != 1 { return errors.New("usage: backup dir") @@ -119,13 +15,18 @@ func commandBackup(repo *khepri.Repository, args []string) error { target := args[0] - id, err := archive_dir(repo, target) + tree, err := khepri.NewTreeFromPath(repo, target) + if err != nil { + return err + } + + id, err := tree.Save(repo) if err != nil { return err } sn := khepri.NewSnapshot(target) - sn.TreeID = id + sn.Content = id snid, err := sn.Save(repo) if err != nil { diff --git a/cmd/khepri/cmd_dump.go b/cmd/khepri/cmd_dump.go new file mode 100644 index 000000000..d0fb09371 --- /dev/null +++ b/cmd/khepri/cmd_dump.go @@ -0,0 +1,90 @@ +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 +} diff --git a/cmd/khepri/cmd_fsck.go b/cmd/khepri/cmd_fsck.go index f85a380c5..8b5d71326 100644 --- a/cmd/khepri/cmd_fsck.go +++ b/cmd/khepri/cmd_fsck.go @@ -41,7 +41,7 @@ func fsck_snapshot(repo *khepri.Repository, id khepri.ID) (bool, error) { return false, err } - return fsck_tree(repo, sn.TreeID) + return fsck_tree(repo, sn.Content) } func commandFsck(repo *khepri.Repository, args []string) error { diff --git a/cmd/khepri/cmd_restore.go b/cmd/khepri/cmd_restore.go index 0f90ab470..db7b6088b 100644 --- a/cmd/khepri/cmd_restore.go +++ b/cmd/khepri/cmd_restore.go @@ -2,44 +2,95 @@ package main import ( "errors" + "fmt" "io" "log" "os" - "path" + "path/filepath" + "syscall" "github.com/fd0/khepri" ) -func restore_file(repo *khepri.Repository, node khepri.Node, target string) error { - log.Printf(" restore file %q\n", target) +func restore_file(repo *khepri.Repository, node *khepri.Node, path string) (err error) { + switch node.Type { + case "file": + // TODO: handle hard links + rd, err := repo.Get(khepri.TYPE_BLOB, node.Content) + if err != nil { + return err + } - rd, err := repo.Get(khepri.TYPE_BLOB, node.Content) + f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0600) + defer f.Close() + if err != nil { + return err + } + + _, err = io.Copy(f, rd) + if err != nil { + return err + } + + case "symlink": + err = os.Symlink(node.LinkTarget, path) + if err != nil { + return err + } + + err = os.Lchown(path, int(node.UID), int(node.GID)) + if err != nil { + return err + } + + f, err := os.OpenFile(path, khepri.O_PATH|syscall.O_NOFOLLOW, 0600) + defer f.Close() + if err != nil { + return err + } + + var utimes = []syscall.Timeval{ + syscall.NsecToTimeval(node.AccessTime.UnixNano()), + syscall.NsecToTimeval(node.ModTime.UnixNano()), + } + err = syscall.Futimes(int(f.Fd()), utimes) + if err != nil { + return err + } + + return nil + case "dev": + err = syscall.Mknod(path, syscall.S_IFBLK|0600, int(node.Device)) + if err != nil { + return err + } + case "chardev": + err = syscall.Mknod(path, syscall.S_IFCHR|0600, int(node.Device)) + if err != nil { + return err + } + case "fifo": + err = syscall.Mkfifo(path, 0600) + if err != nil { + return err + } + case "socket": + // nothing to do, we do not restore sockets + default: + return fmt.Errorf("filetype %q not implemented!\n", node.Type) + } + + err = os.Chmod(path, node.Mode) if err != nil { return err } - f, err := os.OpenFile(target, os.O_CREATE|os.O_WRONLY, 0600) - defer f.Close() + err = os.Chown(path, int(node.UID), int(node.GID)) if err != nil { return err } - _, err = io.Copy(f, rd) - if err != nil { - return err - } - - err = f.Chmod(node.Mode) - if err != nil { - return err - } - - err = f.Chown(int(node.User), int(node.Group)) - if err != nil { - return err - } - - err = os.Chtimes(target, node.AccessTime, node.ModTime) + err = os.Chtimes(path, node.AccessTime, node.ModTime) if err != nil { return err } @@ -47,61 +98,48 @@ func restore_file(repo *khepri.Repository, node khepri.Node, target string) erro return nil } -func restore_dir(repo *khepri.Repository, id khepri.ID, target string) error { - log.Printf(" restore dir %q\n", target) - rd, err := repo.Get(khepri.TYPE_BLOB, id) - if err != nil { - return err - } +func restore_subtree(repo *khepri.Repository, tree *khepri.Tree, path string) { + fmt.Printf("restore_subtree(%s)\n", path) - t := khepri.NewTree() - err = t.Restore(rd) - if err != nil { - return err - } + for _, node := range tree.Nodes { + nodepath := filepath.Join(path, node.Name) + // fmt.Printf("%s:%s\n", node.Type, nodepath) - for _, node := range t.Nodes { - name := path.Base(node.Name) - if name == "." || name == ".." { - return errors.New("invalid path") - } - - nodepath := path.Join(target, name) - if node.Mode.IsDir() { - err = os.Mkdir(nodepath, 0700) + if node.Type == "dir" { + err := os.Mkdir(nodepath, 0700) if err != nil { - return err + fmt.Fprintf(os.Stderr, "%s\n", err) + continue } err = os.Chmod(nodepath, node.Mode) if err != nil { - return err + fmt.Fprintf(os.Stderr, "%s\n", err) + continue } - err = os.Chown(nodepath, int(node.User), int(node.Group)) + err = os.Chown(nodepath, int(node.UID), int(node.GID)) if err != nil { - return err + fmt.Fprintf(os.Stderr, "%s\n", err) + continue } - err = restore_dir(repo, node.Content, nodepath) - if err != nil { - return err - } + restore_subtree(repo, node.Tree, filepath.Join(path, node.Name)) err = os.Chtimes(nodepath, node.AccessTime, node.ModTime) if err != nil { - return err + fmt.Fprintf(os.Stderr, "%s\n", err) + continue } } else { - err = restore_file(repo, node, nodepath) + err := restore_file(repo, node, nodepath) if err != nil { - return err + fmt.Fprintf(os.Stderr, "%s\n", err) + continue } } } - - return nil } func commandRestore(repo *khepri.Repository, args []string) error { @@ -126,11 +164,13 @@ func commandRestore(repo *khepri.Repository, args []string) error { log.Fatalf("error loading snapshot %s", id) } - err = restore_dir(repo, sn.TreeID, target) + tree, err := khepri.NewTreeFromRepo(repo, sn.Content) if err != nil { - return err + log.Fatalf("error loading tree %s", sn.Content) } + restore_subtree(repo, tree, target) + log.Printf("%q restored to %q\n", id, target) return nil diff --git a/cmd/khepri/main.go b/cmd/khepri/main.go index 50479cca4..5219456a8 100644 --- a/cmd/khepri/main.go +++ b/cmd/khepri/main.go @@ -34,6 +34,7 @@ func init() { commands["list"] = commandList commands["snapshots"] = commandSnapshots commands["fsck"] = commandFsck + commands["dump"] = commandDump } func main() { diff --git a/cmd/stat/stat.go b/cmd/stat/stat.go new file mode 100644 index 000000000..5f3671e14 --- /dev/null +++ b/cmd/stat/stat.go @@ -0,0 +1,37 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/fd0/khepri" +) + +func main() { + if len(os.Args) == 1 { + fmt.Printf("usage: %s [file] [file] [...]\n", os.Args[0]) + os.Exit(1) + } + + for _, path := range os.Args[1:] { + fmt.Printf("lstat %s\n", path) + + fi, err := os.Lstat(path) + if err != nil { + fmt.Fprintf(os.Stderr, "%v", err) + continue + } + + node, err := khepri.NodeFromFileInfo(path, fi) + if err != nil { + fmt.Printf("err: %v\n", err) + } + + buf, err := json.MarshalIndent(node, "", " ") + if err != nil { + panic(err) + } + fmt.Printf("%s\n", string(buf)) + } +} diff --git a/cmd/tree_serialise/main.go b/cmd/tree_serialise/main.go new file mode 100644 index 000000000..220f62f38 --- /dev/null +++ b/cmd/tree_serialise/main.go @@ -0,0 +1,222 @@ +package main + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "strings" +) + +func check(err error) { + if err != nil { + panic(err) + } +} + +// References content within a repository. +type ID []byte + +func (id ID) String() string { + return hex.EncodeToString(id) +} + +func (id ID) MarshalJSON() ([]byte, error) { + return json.Marshal(id.String()) +} + +func (id *ID) UnmarshalJSON(b []byte) error { + var s string + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + *id = make([]byte, len(s)/2) + _, err = hex.Decode(*id, []byte(s)) + if err != nil { + return err + } + + return nil +} + +// ParseID converts the given string to an ID. +func ParseID(s string) ID { + b, err := hex.DecodeString(s) + + if err != nil { + panic(err) + } + + return ID(b) +} + +type Repository interface { + Store([]byte) ID + Get(ID) []byte +} + +type Repo map[string][]byte + +func (r Repo) Store(buf []byte) ID { + hash := sha256.New() + _, err := hash.Write(buf) + check(err) + + id := ID(hash.Sum([]byte{})) + r[id.String()] = buf + + return id +} + +func (r Repo) Get(id ID) []byte { + buf, ok := r[id.String()] + if !ok { + panic("no such id") + } + + return buf +} + +func (r Repo) Dump(wr io.Writer) { + for k, v := range r { + _, err := wr.Write([]byte(k)) + check(err) + _, err = wr.Write([]byte(":")) + check(err) + _, err = wr.Write(v) + check(err) + _, err = wr.Write([]byte("\n")) + check(err) + } +} + +type Tree struct { + Nodes []*Node `json:"nodes,omitempty"` +} + +type Node struct { + Name string `json:"name"` + Tree *Tree `json:"tree,omitempty"` + Subtree ID `json:"subtree,omitempty"` + Content ID `json:"content,omitempty"` +} + +func (tree Tree) Save(repo Repository) ID { + // fmt.Printf("nodes: %#v\n", tree.Nodes) + for _, node := range tree.Nodes { + if node.Tree != nil { + node.Subtree = node.Tree.Save(repo) + node.Tree = nil + } + } + + buf, err := json.Marshal(tree) + check(err) + + return repo.Store(buf) +} + +func (tree Tree) PP(wr io.Writer) { + tree.pp(0, wr) +} + +func (tree Tree) pp(indent int, wr io.Writer) { + for _, node := range tree.Nodes { + if node.Tree != nil { + fmt.Printf("%s%s/\n", strings.Repeat(" ", indent), node.Name) + node.Tree.pp(indent+1, wr) + } else { + fmt.Printf("%s%s [%s]\n", strings.Repeat(" ", indent), node.Name, node.Content) + } + + } +} + +func create_tree(path string) *Tree { + dir, err := os.Open(path) + check(err) + + entries, err := dir.Readdir(-1) + check(err) + + tree := &Tree{ + Nodes: make([]*Node, 0, len(entries)), + } + + for _, entry := range entries { + node := &Node{} + node.Name = entry.Name() + + if !entry.Mode().IsDir() && entry.Mode()&os.ModeType != 0 { + fmt.Fprintf(os.Stderr, "skipping %q\n", filepath.Join(path, entry.Name())) + continue + } + + tree.Nodes = append(tree.Nodes, node) + + if entry.IsDir() { + node.Tree = create_tree(filepath.Join(path, entry.Name())) + continue + } + + file, err := os.Open(filepath.Join(path, entry.Name())) + defer file.Close() + check(err) + + hash := sha256.New() + io.Copy(hash, file) + + node.Content = hash.Sum([]byte{}) + } + + return tree +} + +func load_tree(repo Repository, id ID) *Tree { + tree := &Tree{} + + buf := repo.Get(id) + json.Unmarshal(buf, tree) + + for _, node := range tree.Nodes { + if node.Subtree != nil { + node.Tree = load_tree(repo, node.Subtree) + node.Subtree = nil + } + } + + return tree +} + +func main() { + repo := make(Repo) + + tree := create_tree(os.Args[1]) + // encoder := json.NewEncoder(os.Stdout) + // fmt.Println("---------------------------") + // encoder.Encode(tree) + // fmt.Println("---------------------------") + + id := tree.Save(repo) + + // for k, v := range repo { + // fmt.Printf("%s: %s\n", k, v) + // } + + // fmt.Println("---------------------------") + + tree2 := load_tree(repo, id) + tree2.PP(os.Stdout) + // encoder.Encode(tree2) + + // dumpfile, err := os.Create("dump") + // defer dumpfile.Close() + // check(err) + + // repo.Dump(dumpfile) +} diff --git a/cmd/tree_test/khepri-repo/blobs/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a b/cmd/tree_test/khepri-repo/blobs/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a new file mode 100644 index 000000000..9e26dfeeb --- /dev/null +++ b/cmd/tree_test/khepri-repo/blobs/44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/cmd/tree_test/khepri-repo/blobs/655ee6b9ff7fb7324f1e8566eca49c67d251459787765f9c5c6af513e3db0c72 b/cmd/tree_test/khepri-repo/blobs/655ee6b9ff7fb7324f1e8566eca49c67d251459787765f9c5c6af513e3db0c72 new file mode 100644 index 000000000..7a7b553a5 --- /dev/null +++ b/cmd/tree_test/khepri-repo/blobs/655ee6b9ff7fb7324f1e8566eca49c67d251459787765f9c5c6af513e3db0c72 @@ -0,0 +1 @@ +{"nodes":[{"name":"blobs","type":"dir","mode":2147484096,"mtime":"2014-08-11T19:51:11.894770622+02:00","atime":"2014-08-11T19:51:11.894770622+02:00","ctime":"2014-08-11T19:51:11.894770622+02:00","uid":1000,"gid":100,"user":"fd0","inode":428349318,"subtree":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"},{"name":"refs","type":"dir","mode":2147484096,"mtime":"2014-08-11T19:51:11.894770622+02:00","atime":"2014-08-11T19:51:11.894770622+02:00","ctime":"2014-08-11T19:51:11.894770622+02:00","uid":1000,"gid":100,"user":"fd0","inode":4883656,"subtree":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"},{"name":"tmp","type":"dir","mode":2147484096,"mtime":"2014-08-11T19:51:11.894770622+02:00","atime":"2014-08-11T19:51:11.894770622+02:00","ctime":"2014-08-11T19:51:11.894770622+02:00","uid":1000,"gid":100,"user":"fd0","inode":169971890,"subtree":"44136fa355b3678a1146ad16f7e8649e94fb4fc21fe77e8310c060f61caaff8a"}]} \ No newline at end of file diff --git a/cmd/tree_test/khepri-repo/blobs/9e3528071fbfda7702010f2b711174c17df3156b77c14015ce633c9722c0e146 b/cmd/tree_test/khepri-repo/blobs/9e3528071fbfda7702010f2b711174c17df3156b77c14015ce633c9722c0e146 new file mode 100644 index 000000000..6c2868f21 --- /dev/null +++ b/cmd/tree_test/khepri-repo/blobs/9e3528071fbfda7702010f2b711174c17df3156b77c14015ce633c9722c0e146 @@ -0,0 +1 @@ +{"nodes":[{"name":"main.go","type":"file","mode":420,"mtime":"2014-08-10T23:18:15.815999516+02:00","atime":"2014-08-10T23:18:15.815999516+02:00","ctime":"2014-08-10T23:18:15.819332884+02:00","uid":1000,"gid":100,"user":"fd0","inode":193352413,"size":1181,"links":1,"content":"c45d3975908245296eb5730cf4bbbe9d8c39b0736658b5df9beada0739d40569"},{"name":"khepri-repo","type":"dir","mode":2147484096,"mtime":"2014-08-11T19:51:11.894770622+02:00","atime":"2014-08-11T19:51:11.894770622+02:00","ctime":"2014-08-11T19:51:11.894770622+02:00","uid":1000,"gid":100,"user":"fd0","inode":275443328,"subtree":"655ee6b9ff7fb7324f1e8566eca49c67d251459787765f9c5c6af513e3db0c72"}]} \ No newline at end of file diff --git a/cmd/tree_test/main.go b/cmd/tree_test/main.go new file mode 100644 index 000000000..fdf36408b --- /dev/null +++ b/cmd/tree_test/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "fmt" + "os" + "strings" + + "github.com/fd0/khepri" +) + +func check(err error) { + if err == nil { + return + } + + fmt.Fprintf(os.Stderr, "error: %v\n", err) + os.Exit(1) +} + +func save(repo *khepri.Repository, path string) { + tree, err := khepri.NewTreeFromPath(repo, path) + + check(err) + + id, err := tree.Save(repo) + + fmt.Printf("saved tree as %s\n", id) +} + +func restore(repo *khepri.Repository, idstr string) { + id, err := khepri.ParseID(idstr) + check(err) + + tree, err := khepri.NewTreeFromRepo(repo, id) + check(err) + + walk(0, tree) +} + +func walk(indent int, tree *khepri.Tree) { + for _, node := range tree.Nodes { + if node.Type == "dir" { + fmt.Printf("%s%s:%s/\n", strings.Repeat(" ", indent), node.Type, node.Name) + walk(indent+1, node.Tree) + } else { + fmt.Printf("%s%s:%s\n", strings.Repeat(" ", indent), node.Type, node.Name) + } + } +} + +func main() { + if len(os.Args) != 3 { + fmt.Fprintf(os.Stderr, "usage: %s [save|restore] DIR\n", os.Args[0]) + os.Exit(1) + } + + command := os.Args[1] + arg := os.Args[2] + + repo, err := khepri.NewRepository("khepri-repo") + check(err) + + switch command { + case "save": + save(repo, arg) + case "restore": + restore(repo, arg) + } +} diff --git a/repository.go b/repository.go index 68e1065cb..4309b7e07 100644 --- a/repository.go +++ b/repository.go @@ -31,9 +31,11 @@ func (n Name) Encode() string { return url.QueryEscape(string(n)) } +type HashFunc func() hash.Hash + type Repository struct { path string - hash func() hash.Hash + hash HashFunc } type Type int @@ -99,6 +101,11 @@ func (r *Repository) create() error { return nil } +// SetHash changes the hash function used for deriving IDs. Default is SHA256. +func (r *Repository) SetHash(h HashFunc) { + r.hash = h +} + // Path returns the directory used for this repository. func (r *Repository) Path() string { return r.path diff --git a/snapshot.go b/snapshot.go index c35bdcda7..d6da7b099 100644 --- a/snapshot.go +++ b/snapshot.go @@ -2,6 +2,7 @@ package khepri import ( "encoding/json" + "fmt" "os" "os/user" "time" @@ -9,12 +10,14 @@ import ( type Snapshot struct { Time time.Time `json:"time"` - TreeID ID `json:"tree"` + Content ID `json:"content"` + Tree *Tree `json:"-"` Dir string `json:"dir"` Hostname string `json:"hostname,omitempty"` Username string `json:"username,omitempty"` UID string `json:"uid,omitempty"` GID string `json:"gid,omitempty"` + id ID `json:omit` } func NewSnapshot(dir string) *Snapshot { @@ -39,7 +42,7 @@ func NewSnapshot(dir string) *Snapshot { } func (sn *Snapshot) Save(repo *Repository) (ID, error) { - if sn.TreeID == nil { + if sn.Content == nil { panic("Snapshot.Save() called with nil tree id") } @@ -59,7 +62,9 @@ func (sn *Snapshot) Save(repo *Repository) (ID, error) { return nil, err } - return <-id_ch, nil + sn.id = <-id_ch + + return sn.id, nil } func LoadSnapshot(repo *Repository, id ID) (*Snapshot, error) { @@ -78,5 +83,15 @@ func LoadSnapshot(repo *Repository, id ID) (*Snapshot, error) { return nil, err } + sn.id = id + return sn, nil } + +func (sn *Snapshot) ID() ID { + return sn.id +} + +func (sn *Snapshot) String() string { + return fmt.Sprintf("", sn.Dir, sn.Time.Format(time.RFC822Z)) +} diff --git a/snapshot_test.go b/snapshot_test.go index c294312d7..622407377 100644 --- a/snapshot_test.go +++ b/snapshot_test.go @@ -17,7 +17,7 @@ func TestSnapshot(t *testing.T) { }() sn := khepri.NewSnapshot("/home/foobar") - sn.TreeID, err = khepri.ParseID("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2") + sn.Content, err = khepri.ParseID("c3ab8ff13720e8ad9047dd39466b3c8974e592c2fa383d4a3960714caef0c4f2") ok(t, err) sn.Time, err = time.Parse(time.RFC3339Nano, "2014-08-03T17:49:05.378595539+02:00") ok(t, err) diff --git a/test/fake-data.tar.gz b/test/fake-data.tar.gz index 526b65a641d7145704c1a3402f834ab880da76f7..58502ab4f59808aad2deb34af0d6ca537ec8bf0c 100644 GIT binary patch literal 177701 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

thKh&Fwhb!2fm6ttc-Bd{>9I~ir(TMd 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 literal 177445 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

A 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 F{{w2avNZqz diff --git a/tree.go b/tree.go index f2f3c72a4..4e90e32c1 100644 --- a/tree.go +++ b/tree.go @@ -2,54 +2,238 @@ package khepri import ( "encoding/json" + "fmt" "io" "os" + "os/user" + "path/filepath" + "strconv" "syscall" "time" ) type Tree struct { - Nodes []Node `json:"nodes"` + Nodes []*Node `json:"nodes,omitempty"` } type Node struct { Name string `json:"name"` - Mode os.FileMode `json:"mode"` - ModTime time.Time `json:"mtime"` - AccessTime time.Time `json:"atime"` - User uint32 `json:"user"` - Group uint32 `json:"group"` + Type string `json:"type"` + Mode os.FileMode `json:"mode,omitempty"` + ModTime time.Time `json:"mtime,omitempty"` + AccessTime time.Time `json:"atime,omitempty"` + ChangeTime time.Time `json:"ctime,omitempty"` + UID uint32 `json:"uid"` + GID uint32 `json:"gid"` + User string `json:"user,omitempty"` + Group string `json:"group,omitempty"` + Inode uint64 `json:"inode,omitempty"` + Size uint64 `json:"size,omitempty"` + Links uint64 `json:"links,omitempty"` + LinkTarget string `json:"linktarget,omitempty"` + Device uint64 `json:"device,omitempty"` Content ID `json:"content,omitempty"` + Subtree ID `json:"subtree,omitempty"` + Tree *Tree `json:"-"` } func NewTree() *Tree { return &Tree{ - Nodes: []Node{}, + Nodes: []*Node{}, } } -func (t *Tree) Restore(r io.Reader) error { - dec := json.NewDecoder(r) - return dec.Decode(t) +func NewTreeFromPath(repo *Repository, dir string) (*Tree, error) { + fd, err := os.Open(dir) + defer fd.Close() + if err != nil { + return nil, err + } + + entries, err := fd.Readdir(-1) + if err != nil { + return nil, err + } + + tree := &Tree{ + Nodes: make([]*Node, 0, len(entries)), + } + + for _, entry := range entries { + path := filepath.Join(dir, entry.Name()) + node, err := NodeFromFileInfo(path, entry) + if err != nil { + return nil, err + } + + tree.Nodes = append(tree.Nodes, node) + + if entry.IsDir() { + node.Tree, err = NewTreeFromPath(repo, path) + if err != nil { + return nil, err + } + continue + } + + if node.Type == "file" { + file, err := os.Open(path) + defer file.Close() + if err != nil { + return nil, err + } + + wr, idch, err := repo.Create(TYPE_BLOB) + if err != nil { + return nil, err + } + + io.Copy(wr, file) + err = wr.Close() + if err != nil { + return nil, err + } + + node.Content = <-idch + } + } + + return tree, nil } -func (t *Tree) Save(w io.Writer) error { - enc := json.NewEncoder(w) - return enc.Encode(t) +func (tree *Tree) Save(repo *Repository) (ID, error) { + for _, node := range tree.Nodes { + if node.Tree != nil { + var err error + node.Subtree, err = node.Tree.Save(repo) + if err != nil { + return nil, err + } + } + } + + buf, err := json.Marshal(tree) + if err != nil { + return nil, err + } + + wr, idch, err := repo.Create(TYPE_BLOB) + if err != nil { + return nil, err + } + + _, err = wr.Write(buf) + if err != nil { + return nil, err + } + + err = wr.Close() + if err != nil { + return nil, err + } + + return <-idch, nil } -func NodeFromFileInfo(fi os.FileInfo) Node { - node := Node{ +func NewTreeFromRepo(repo *Repository, id ID) (*Tree, error) { + tree := NewTree() + + rd, err := repo.Get(TYPE_BLOB, id) + defer rd.Close() + if err != nil { + return nil, err + } + + decoder := json.NewDecoder(rd) + + err = decoder.Decode(tree) + if err != nil { + return nil, err + } + + for _, node := range tree.Nodes { + if node.Subtree != nil { + node.Tree, err = NewTreeFromRepo(repo, node.Subtree) + if err != nil { + return nil, err + } + } + } + + return tree, nil +} + +// TODO: make sure that node.Type is valid + +func (node *Node) fill_extra(path string, fi os.FileInfo) (err error) { + stat, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return + } + + node.ChangeTime = time.Unix(stat.Ctim.Unix()) + node.AccessTime = time.Unix(stat.Atim.Unix()) + node.UID = stat.Uid + node.GID = stat.Gid + + if u, nil := user.LookupId(strconv.Itoa(int(stat.Uid))); err == nil { + node.User = u.Username + } + + // TODO: implement getgrnam() + // if g, nil := user.LookupId(strconv.Itoa(int(stat.Uid))); err == nil { + // node.User = u.Username + // } + + node.Inode = stat.Ino + + switch node.Type { + case "file": + node.Size = uint64(stat.Size) + node.Links = stat.Nlink + case "dir": + // nothing to do + case "symlink": + node.LinkTarget, err = os.Readlink(path) + case "dev": + node.Device = stat.Rdev + case "chardev": + node.Device = stat.Rdev + case "fifo": + // nothing to do + case "socket": + // nothing to do + default: + panic(fmt.Sprintf("invalid node type %q", node.Type)) + } + + return err +} + +func NodeFromFileInfo(path string, fi os.FileInfo) (*Node, error) { + node := &Node{ Name: fi.Name(), - Mode: fi.Mode(), + Mode: fi.Mode() & os.ModePerm, ModTime: fi.ModTime(), } - if stat, ok := fi.Sys().(*syscall.Stat_t); ok { - node.User = stat.Uid - node.Group = stat.Gid - node.AccessTime = time.Unix(stat.Atim.Unix()) + switch fi.Mode() & (os.ModeType | os.ModeCharDevice) { + case 0: + node.Type = "file" + case os.ModeDir: + node.Type = "dir" + case os.ModeSymlink: + node.Type = "symlink" + case os.ModeDevice | os.ModeCharDevice: + node.Type = "chardev" + case os.ModeDevice: + node.Type = "dev" + case os.ModeNamedPipe: + node.Type = "fifo" + case os.ModeSocket: + node.Type = "socket" } - return node + err := node.fill_extra(path, fi) + return node, err } diff --git a/tree_test.go b/tree_test.go deleted file mode 100644 index cd8403e79..000000000 --- a/tree_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package khepri_test - -import ( - "bytes" - "strings" - "testing" - "time" - - "github.com/fd0/khepri" -) - -func parseTime(str string) time.Time { - t, err := time.Parse(time.RFC3339Nano, str) - if err != nil { - panic(err) - } - - return t -} - -func TestTree(t *testing.T) { - var tree = &khepri.Tree{ - Nodes: []khepri.Node{ - khepri.Node{ - Name: "foobar", - Mode: 0755, - ModTime: parseTime("2014-04-20T22:16:54.161401+02:00"), - AccessTime: parseTime("2014-04-21T22:16:54.161401+02:00"), - User: 1000, - Group: 1001, - Content: []byte{0x41, 0x42, 0x43}, - }, - khepri.Node{ - Name: "baz", - Mode: 0755, - User: 1000, - ModTime: parseTime("2014-04-20T22:16:54.161401+02:00"), - AccessTime: parseTime("2014-04-21T22:16:54.161401+02:00"), - Group: 1001, - Content: []byte("\xde\xad\xbe\xef\xba\xdc\x0d\xe0"), - }, - }, - } - - const raw = `{"nodes":[{"name":"foobar","mode":493,"mtime":"2014-04-20T22:16:54.161401+02:00","atime":"2014-04-21T22:16:54.161401+02:00","user":1000,"group":1001,"content":"414243"},{"name":"baz","mode":493,"mtime":"2014-04-20T22:16:54.161401+02:00","atime":"2014-04-21T22:16:54.161401+02:00","user":1000,"group":1001,"content":"deadbeefbadc0de0"}]}` - - // test save - buf := &bytes.Buffer{} - - tree.Save(buf) - equals(t, raw, strings.TrimRight(buf.String(), "\n")) - - tree2 := new(khepri.Tree) - err := tree2.Restore(buf) - ok(t, err) - equals(t, tree, tree2) - - // test nodes for equality - for i, n := range tree.Nodes { - equals(t, n.Content, tree2.Nodes[i].Content) - } - - // test restore - buf = bytes.NewBufferString(raw) - - tree2 = new(khepri.Tree) - err = tree2.Restore(buf) - ok(t, err) - - // test if tree has correctly been restored - equals(t, tree, tree2) -} diff --git a/zerrors_linux.go b/zerrors_linux.go new file mode 100644 index 000000000..8ba94670a --- /dev/null +++ b/zerrors_linux.go @@ -0,0 +1,5 @@ +package khepri + +// 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 +const O_PATH = 010000000