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

@@ -3,13 +3,15 @@ package backup
import (
"crypto/sha1"
"encoding/hex"
"github.com/apex/log"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"io"
"os"
"path"
"sync"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
)
type AdapterType string
@@ -19,6 +21,38 @@ const (
S3BackupAdapter AdapterType = "s3"
)
type Request struct {
Adapter AdapterType `json:"adapter"`
Uuid string `json:"uuid"`
Ignore string `json:"ignore"`
}
// AsBackup returns a new backup adapter based on the request value.
func (r *Request) AsBackup() (BackupInterface, error) {
var adapter BackupInterface
switch r.Adapter {
case LocalBackupAdapter:
adapter = &LocalBackup{
Backup{
Uuid: r.Uuid,
Ignore: r.Ignore,
adapter: LocalBackupAdapter,
},
}
case S3BackupAdapter:
adapter = &S3Backup{
Backup: Backup{
Uuid: r.Uuid,
Ignore: r.Ignore,
adapter: S3BackupAdapter,
},
}
default:
return nil, errors.New("server/backup: unsupported adapter type: " + string(r.Adapter))
}
return adapter, nil
}
type ArchiveDetails struct {
Checksum string `json:"checksum"`
ChecksumType string `json:"checksum_type"`

View File

@@ -2,8 +2,11 @@ package backup
import (
"errors"
"github.com/pterodactyl/wings/server/filesystem"
"os"
"github.com/mholt/archiver/v3"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
)
type LocalBackup struct {
@@ -12,8 +15,8 @@ type LocalBackup struct {
var _ BackupInterface = (*LocalBackup)(nil)
// Locates the backup for a server and returns the local path. This will obviously only
// work if the backup was created as a local backup.
// LocateLocal finds the backup for a server and returns the local path. This
// will obviously only work if the backup was created as a local backup.
func LocateLocal(uuid string) (*LocalBackup, os.FileInfo, error) {
b := &LocalBackup{
Backup{
@@ -34,18 +37,18 @@ func LocateLocal(uuid string) (*LocalBackup, os.FileInfo, error) {
return b, st, nil
}
// Removes a backup from the system.
// Remove removes a backup from the system.
func (b *LocalBackup) Remove() error {
return os.Remove(b.Path())
}
// Attaches additional context to the log output for this backup.
// WithLogContext attaches additional context to the log output for this backup.
func (b *LocalBackup) WithLogContext(c map[string]interface{}) {
b.logContext = c
}
// Generates a backup of the selected files and pushes it to the defined location
// for this instance.
// Generate generates a backup of the selected files and pushes it to the
// defined location for this instance.
func (b *LocalBackup) Generate(basePath, ignore string) (*ArchiveDetails, error) {
a := &filesystem.Archive{
BasePath: basePath,
@@ -60,3 +63,17 @@ func (b *LocalBackup) Generate(basePath, ignore string) (*ArchiveDetails, error)
return b.Details(), nil
}
// Restore restores a backup to the provided server's root data directory.
func (b *LocalBackup) Restore(s *server.Server) error {
return archiver.Walk(b.Path(), func(f archiver.File) error {
if f.IsDir() {
return nil
}
name, err := filesystem.ExtractArchiveSourceName(f, "/")
if err != nil {
return err
}
return s.Filesystem().Writefile(name, f)
})
}

View File

@@ -1,42 +0,0 @@
package backup
import (
"errors"
"fmt"
)
type Request struct {
Adapter AdapterType `json:"adapter"`
Uuid string `json:"uuid"`
Ignore string `json:"ignore"`
}
// Generates a new local backup struct.
func (r *Request) NewLocalBackup() (*LocalBackup, error) {
if r.Adapter != LocalBackupAdapter {
return nil, errors.New(fmt.Sprintf("cannot create local backup using [%s] adapter", r.Adapter))
}
return &LocalBackup{
Backup{
Uuid: r.Uuid,
Ignore: r.Ignore,
adapter: LocalBackupAdapter,
},
}, nil
}
// Generates a new S3 backup struct.
func (r *Request) NewS3Backup() (*S3Backup, error) {
if r.Adapter != S3BackupAdapter {
return nil, errors.New(fmt.Sprintf("cannot create s3 backup using [%s] adapter", r.Adapter))
}
return &S3Backup{
Backup: Backup{
Uuid: r.Uuid,
Ignore: r.Ignore,
adapter: S3BackupAdapter,
},
}, nil
}