diff options
author | Tom Fawssett <tom.fawssett@gmail.com> | 2017-06-24 16:01:12 +0100 |
---|---|---|
committer | Tom Fawssett <tom.fawssett@gmail.com> | 2017-06-24 16:01:12 +0100 |
commit | 30dea40a20e45bdb0d32fd7c373f07e1dccbe794 (patch) | |
tree | af572892aeb35816415c0b311d12438df174e812 /system/backup/archive.go | |
parent | f4c5d79810352d42ebcab92b52e7c53b9bc782b3 (diff) |
Move file system archive code into backup package
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 +} |