diff options
-rw-r--r-- | main.go | 17 | ||||
-rw-r--r-- | repo.go | 64 |
2 files changed, 73 insertions, 8 deletions
@@ -1,19 +1,20 @@ package main import ( + "fmt" "os" ) func main() { - path := "." - if len(os.Args) > 1 { - path = os.Args[1] + if len(os.Args) != 3 { + fmt.Println("usage: dna-backup <source> <dest>") + os.Exit(1) } - files := make(chan File) - chunks := make(chan []byte) - go ListFiles(path, files) - go ReadFiles(files, chunks) - StoreChunks(".", chunks) + source := os.Args[1] + dest := os.Args[2] + + os.MkdirAll(dest, 0775) + Commit(source, dest) } @@ -1,13 +1,39 @@ +/* +Manage a deduplicated versionned backups repository. + +Sample repository: + +``` +repo/ +├── 00000/ +│ ├── chunks/ +│ │ ├── 000000000000000 +│ │ ├── 000000000000001 +│ │ ├── 000000000000002 +│ │ ├── 000000000000003 +│ ├── dentries +│ └── recipe +└── 00001/ + ├── chunks/ + │ ├── 000000000000000 + │ ├── 000000000000001 + ├── dentries + └── recipe +``` +*/ + package main import ( "fmt" "io" "io/fs" + "io/ioutil" "log" "os" "path" "path/filepath" + "strconv" ) const ( @@ -19,6 +45,44 @@ type File struct { Size int64 } +func Commit(source string, repo string) { + latest := GetLastVersion(repo) + new := latest + 1 + newPath := path.Join(repo, fmt.Sprintf("%05d", new)) + newChunkPath := path.Join(newPath, "chunks") + os.Mkdir(newPath, 0775) + os.Mkdir(newChunkPath, 0775) + files := make(chan File) + newChunks := make(chan []byte) + oldChunks := make(chan []byte) + go LoadChunks(repo, oldChunks) + go ListFiles(source, files) + go ReadFiles(files, newChunks) + StoreChunks(newChunkPath, newChunks) +} + +func GetLastVersion(repo string) int { + v := -1 + files, err := ioutil.ReadDir(repo) + if err != nil { + log.Fatalln(err) + } + for _, f := range files { + if !f.IsDir() { + continue + } + num, err := strconv.Atoi(f.Name()) + if err != nil { + log.Println(err) + continue + } + if num > v { + v = num + } + } + return v +} + func ListFiles(path string, files chan<- File) { err := filepath.Walk(path, func(p string, i fs.FileInfo, err error) error { |