diff options
author | Steve Manuel <nilslice@gmail.com> | 2017-06-26 16:33:41 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-26 16:33:41 -0700 |
commit | 08bab226d6b998eb5cf87e4be1db45e89fb9f772 (patch) | |
tree | aba0be8dbd8c0ed630439a302fffcf5c078eeb21 /system/backup/archive.go | |
parent | cd6be5ebe16f3ee815e12d3022dfb79e4163d867 (diff) | |
parent | 0a1d7d9cd8ad1ac01c8fcd4d3b4fef57cffd4cb0 (diff) |
Merge pull request #168 from tom-f/ponzu-dev
Add backup routine to search
Diffstat (limited to 'system/backup/archive.go')
-rw-r--r-- | system/backup/archive.go | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/system/backup/archive.go b/system/backup/archive.go new file mode 100644 index 0000000..0a8b964 --- /dev/null +++ b/system/backup/archive.go @@ -0,0 +1,95 @@ +package backup + +import ( + "archive/tar" + "compress/gzip" + "context" + "fmt" + "io" + "os" + "path/filepath" +) + +// ArchiveFS walks the filesystem starting from basedir writing files encountered +// tarred and gzipped to the provided writer +func ArchiveFS(ctx context.Context, basedir string, w io.Writer) error { + gz := gzip.NewWriter(w) + tarball := tar.NewWriter(gz) + + errChan := make(chan error, 1) + walkFn := func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + + hdr, err := tar.FileInfoHeader(info, "") + if err != nil { + return err + } + + hdr.Name = path + + err = tarball.WriteHeader(hdr) + if err != nil { + return err + } + + if !info.IsDir() { + src, err := os.Open(path) + if err != nil { + return err + } + defer src.Close() + + _, err = io.Copy(tarball, src) + if err != nil { + return err + } + + err = tarball.Flush() + if err != nil { + return err + } + + err = gz.Flush() + if err != nil { + return err + } + } + + return nil + } + + // stop processing if we get a cancellation signal + err := filepath.Walk(basedir, func(path string, info os.FileInfo, err error) error { + go func() { errChan <- walkFn(path, info, err) }() + + select { + case <-ctx.Done(): + if err := ctx.Err(); err != nil { + return err + } + case err := <-errChan: + if err != nil { + return err + } + } + + return nil + }) + if err != nil { + fmt.Println(err) + return err + } + + err = gz.Close() + if err != nil { + return err + } + err = tarball.Close() + if err != nil { + return err + } + + return nil +} |