2020-04-04 05:17:26 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"github.com/mholt/archiver/v3"
|
|
|
|
"github.com/pterodactyl/wings/config"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Archiver represents a Server Archiver.
|
|
|
|
type Archiver struct {
|
|
|
|
Server *Server
|
|
|
|
}
|
|
|
|
|
|
|
|
// ArchivePath returns the path to the server's archive.
|
|
|
|
func (a *Archiver) ArchivePath() string {
|
2020-04-04 06:17:32 +00:00
|
|
|
return filepath.Join(config.Get().System.ArchiveDirectory, a.ArchiveName())
|
2020-04-04 05:17:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ArchiveName returns the name of the server's archive.
|
|
|
|
func (a *Archiver) ArchiveName() string {
|
|
|
|
return a.Server.Uuid + ".tar.gz"
|
|
|
|
}
|
|
|
|
|
|
|
|
// Exists returns a boolean based off if the archive exists.
|
|
|
|
func (a *Archiver) Exists() bool {
|
|
|
|
if _, err := os.Stat(a.ArchivePath()); os.IsNotExist(err) {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
2020-04-04 06:17:32 +00:00
|
|
|
// Stat stats the archive file.
|
2020-04-04 05:17:26 +00:00
|
|
|
func (a *Archiver) Stat() (*Stat, error) {
|
|
|
|
return a.Server.Filesystem.unsafeStat(a.ArchivePath())
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
path := a.Server.Filesystem.Path()
|
|
|
|
|
|
|
|
// 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 {
|
|
|
|
files = append(files, filepath.Join(path, file.Name()))
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
if err := os.Remove(a.ArchivePath()); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-04 05:17:26 +00:00
|
|
|
return archiver.NewTarGz().Archive(files, a.ArchivePath())
|
|
|
|
}
|
|
|
|
|
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 {
|
|
|
|
if err := os.Remove(a.ArchivePath()); err != nil {
|
|
|
|
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) {
|
|
|
|
file, err := os.Open(a.ArchivePath())
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
hash := sha256.New()
|
|
|
|
if _, err := io.Copy(hash, file); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return hex.EncodeToString(hash.Sum(nil)), nil
|
|
|
|
}
|