Initial untested pass at restoring from local backups

This commit is contained in:
Dane Everitt
2021-01-16 18:06:22 -08:00
parent 6a286fb444
commit 7dd0acebc0
6 changed files with 183 additions and 116 deletions

View File

@@ -74,23 +74,10 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
if f.IsDir() {
return nil
}
var name string
switch s := f.Sys().(type) {
case *tar.Header:
name = s.Name
case *gzip.Header:
name = s.Name
case *zip.FileHeader:
name = s.Name
default:
return &Error{
code: ErrCodeUnknownError,
resolved: filepath.Join(dir, f.Name()),
err: errors.New(fmt.Sprintf("could not parse underlying data source with type: %s", reflect.TypeOf(s).String())),
}
name, err := ExtractArchiveSourceName(f, dir)
if err != nil {
return err
}
p := filepath.Join(dir, name)
// If it is ignored, just don't do anything with the file and skip over it.
if err := fs.IsIgnored(p); err != nil {
@@ -109,3 +96,23 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
}
return nil
}
// ExtractArchiveSourceName looks for the provided archiver.File's name if it is
// a type that is supported, otherwise it returns an error to the caller.
func ExtractArchiveSourceName(f archiver.File, dir string) (name string, err error) {
switch s := f.Sys().(type) {
case *tar.Header:
name = s.Name
case *gzip.Header:
name = s.Name
case *zip.FileHeader:
name = s.Name
default:
err = &Error{
code: ErrCodeUnknownError,
resolved: filepath.Join(dir, f.Name()),
err: errors.New(fmt.Sprintf("could not parse underlying data source with type: %s", reflect.TypeOf(s).String())),
}
}
return name, err
}

View File

@@ -11,6 +11,7 @@ import (
"strconv"
"strings"
"sync"
"sync/atomic"
"time"
"emperror.dev/errors"
@@ -124,7 +125,8 @@ func (fs *Filesystem) Readfile(p string, w io.Writer) error {
}
// Writefile writes a file to the system. If the file does not already exist one
// will be created.
// will be created. This will also properly recalculate the disk space used by
// the server when writing new files or modifying existing ones.
func (fs *Filesystem) Writefile(p string, r io.Reader) error {
cleaned, err := fs.SafePath(p)
if err != nil {
@@ -365,8 +367,21 @@ func (fs *Filesystem) Copy(p string) error {
return fs.Writefile(path.Join(relative, n), source)
}
// Deletes a file or folder from the system. Prevents the user from accidentally
// (or maliciously) removing their root server data directory.
// TruncateRootDirectory removes _all_ files and directories from a server's
// data directory and resets the used disk space to zero.
func (fs *Filesystem) TruncateRootDirectory() error {
if err := os.RemoveAll(fs.Path()); err != nil {
return err
}
if err := os.Mkdir(fs.Path(), 0755); err != nil {
return err
}
atomic.StoreInt64(&fs.diskUsed, 0)
return nil
}
// Delete removes a file or folder from the system. Prevents the user from
// accidentally (or maliciously) removing their root server data directory.
func (fs *Filesystem) Delete(p string) error {
wg := sync.WaitGroup{}
// This is one of the few (only?) places in the codebase where we're explicitly not using