2020-04-04 05:17:26 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"github.com/mholt/archiver/v3"
|
2020-09-27 19:24:08 +00:00
|
|
|
"github.com/pkg/errors"
|
2020-04-04 05:17:26 +00:00
|
|
|
"github.com/pterodactyl/wings/config"
|
2020-09-27 19:24:08 +00:00
|
|
|
"github.com/pterodactyl/wings/server/filesystem"
|
2020-04-04 05:17:26 +00:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Archiver represents a Server Archiver.
|
|
|
|
type Archiver struct {
|
|
|
|
Server *Server
|
|
|
|
}
|
|
|
|
|
2020-09-27 19:24:08 +00:00
|
|
|
// Path returns the path to the server's archive.
|
|
|
|
func (a *Archiver) Path() string {
|
|
|
|
return filepath.Join(config.Get().System.ArchiveDirectory, a.Name())
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
2020-09-27 19:24:08 +00:00
|
|
|
// Name returns the name of the server's archive.
|
|
|
|
func (a *Archiver) Name() string {
|
2020-07-20 00:53:41 +00:00
|
|
|
return a.Server.Id() + ".tar.gz"
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Exists returns a boolean based off if the archive exists.
|
|
|
|
func (a *Archiver) Exists() bool {
|
2020-09-27 19:24:08 +00:00
|
|
|
if _, err := os.Stat(a.Path()); os.IsNotExist(err) {
|
2020-04-04 05:17:26 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-04-04 06:17:32 +00:00
|
|
|
// Stat stats the archive file.
|
2020-09-27 19:24:08 +00:00
|
|
|
func (a *Archiver) Stat() (*filesystem.Stat, error) {
|
|
|
|
s, err := os.Stat(a.Path())
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.WithStack(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return &filesystem.Stat{
|
|
|
|
Info: s,
|
|
|
|
Mimetype: "application/tar+gzip",
|
|
|
|
}, nil
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 06:17:32 +00:00
|
|
|
// Archive creates an archive of the server and deletes the previous one.
|
2020-04-04 05:17:26 +00:00
|
|
|
func (a *Archiver) Archive() error {
|
2020-09-27 19:24:08 +00:00
|
|
|
path := a.Server.Filesystem().Path()
|
2020-04-04 05:17:26 +00:00
|
|
|
|
|
|
|
// Get the list of root files and directories to archive.
|
|
|
|
var files []string
|
|
|
|
fileInfo, err := ioutil.ReadDir(path)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, file := range fileInfo {
|
2020-09-27 19:24:08 +00:00
|
|
|
f, err := a.Server.Filesystem().SafeJoin(path, file)
|
2020-07-18 18:40:38 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
files = append(files, f)
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
2020-04-04 06:17:32 +00:00
|
|
|
stat, err := a.Stat()
|
|
|
|
if err != nil && !os.IsNotExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the file exists.
|
|
|
|
if stat != nil {
|
2020-09-27 19:24:08 +00:00
|
|
|
if err := os.Remove(a.Path()); err != nil {
|
2020-04-04 06:17:32 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-27 19:24:08 +00:00
|
|
|
return archiver.NewTarGz().Archive(files, a.Path())
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
2020-04-05 00:31:18 +00:00
|
|
|
// DeleteIfExists deletes the archive if it exists.
|
|
|
|
func (a *Archiver) DeleteIfExists() error {
|
|
|
|
stat, err := a.Stat()
|
|
|
|
if err != nil && !os.IsNotExist(err) {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if the file exists.
|
|
|
|
if stat != nil {
|
2020-09-27 19:24:08 +00:00
|
|
|
if err := os.Remove(a.Path()); err != nil {
|
2020-04-05 00:31:18 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-04-04 05:17:26 +00:00
|
|
|
// Checksum computes a SHA256 checksum of the server's archive.
|
|
|
|
func (a *Archiver) Checksum() (string, error) {
|
2020-09-27 19:24:08 +00:00
|
|
|
file, err := os.Open(a.Path())
|
2020-04-04 05:17:26 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
hash := sha256.New()
|
2020-08-24 00:18:40 +00:00
|
|
|
|
|
|
|
buf := make([]byte, 1024*4)
|
|
|
|
if _, err := io.CopyBuffer(hash, file, buf); err != nil {
|
2020-04-04 05:17:26 +00:00
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return hex.EncodeToString(hash.Sum(nil)), nil
|
|
|
|
}
|