summaryrefslogtreecommitdiff
path: root/system
diff options
context:
space:
mode:
Diffstat (limited to 'system')
-rw-r--r--system/admin/upload/backup.go91
-rw-r--r--system/backup/archive.go95
2 files changed, 102 insertions, 84 deletions
diff --git a/system/admin/upload/backup.go b/system/admin/upload/backup.go
index b4f6393..9dc9e31 100644
--- a/system/admin/upload/backup.go
+++ b/system/admin/upload/backup.go
@@ -1,8 +1,6 @@
package upload
import (
- "archive/tar"
- "compress/gzip"
"context"
"fmt"
"io"
@@ -10,6 +8,8 @@ import (
"os"
"path/filepath"
"time"
+
+ "github.com/ponzu-cms/ponzu/system/backup"
)
// Backup creates an archive of a project's uploads and writes it
@@ -18,105 +18,28 @@ func Backup(ctx context.Context, res http.ResponseWriter) error {
ts := time.Now().Unix()
filename := fmt.Sprintf("uploads-%d.bak.tar.gz", ts)
tmp := os.TempDir()
- backup := filepath.Join(tmp, filename)
+ bk := filepath.Join(tmp, filename)
// create uploads-{stamp}.bak.tar.gz
- f, err := os.Create(backup)
+ f, err := os.Create(bk)
if err != nil {
return err
}
- // loop through directory and gzip files
- // add all to uploads.bak.tar.gz tarball
- gz := gzip.NewWriter(f)
- 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("uploads", func(path string, info os.FileInfo, err error) error {
- go func() { errChan <- walkFn(path, info, err) }()
+ err = backup.ArchiveFS(ctx, "uploads", f)
- 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
- }
err = f.Close()
if err != nil {
return err
}
// write data to response
- data, err := os.Open(backup)
+ data, err := os.Open(bk)
if err != nil {
return err
}
defer data.Close()
- defer os.Remove(backup)
+ defer os.Remove(bk)
disposition := `attachment; filename=%s`
info, err := data.Stat()
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
+}