Refactor filesystem to not be dependent on a server struct

This commit is contained in:
Dane Everitt
2020-09-27 12:24:08 -07:00
parent de30e2fcc9
commit 0f7bb1a371
27 changed files with 1203 additions and 1088 deletions

View File

@@ -7,6 +7,7 @@ import (
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
"net/http"
"os"
"strings"
@@ -105,9 +106,9 @@ func (e *RequestError) AbortFilesystemError(c *gin.Context) {
return
}
if errors.Is(e.Err, server.ErrNotEnoughDiskSpace) {
if errors.Is(e.Err, filesystem.ErrNotEnoughDiskSpace) {
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
"error": server.ErrNotEnoughDiskSpace.Error(),
"error": "There is not enough disk space available to perform that action.",
})
return
}
@@ -126,6 +127,13 @@ func (e *RequestError) AbortFilesystemError(c *gin.Context) {
return
}
if strings.HasSuffix(e.Err.Error(), "file name too long") {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "Cannot perform that action: file name is too long.",
})
return
}
e.AbortWithServerError(c)
}

View File

@@ -70,7 +70,7 @@ func getDownloadFile(c *gin.Context) {
return
}
p, _ := s.Filesystem.SafePath(token.FilePath)
p, _ := s.Filesystem().SafePath(token.FilePath)
st, err := os.Stat(p)
// If there is an error or we're somehow trying to download a directory, just
// respond with the appropriate error.

View File

@@ -228,7 +228,7 @@ func deleteServer(c *gin.Context) {
"error": errors.WithStack(err),
}).Warn("failed to remove server files during deletion process")
}
}(s.Filesystem.Path())
}(s.Filesystem().Path())
var uuid = s.Id()
server.GetServers().Remove(func(s2 *server.Server) bool {

View File

@@ -7,6 +7,7 @@ import (
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
"golang.org/x/sync/errgroup"
"mime/multipart"
"net/http"
@@ -29,7 +30,7 @@ func getServerFileContents(c *gin.Context) {
}
p = "/" + strings.TrimLeft(p, "/")
cleaned, err := s.Filesystem.SafePath(p)
cleaned, err := s.Filesystem().SafePath(p)
if err != nil {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The file requested could not be found.",
@@ -37,7 +38,7 @@ func getServerFileContents(c *gin.Context) {
return
}
st, err := s.Filesystem.Stat(cleaned)
st, err := s.Filesystem().Stat(cleaned)
if err != nil {
TrackedServerError(err, s).AbortWithServerError(c)
return
@@ -80,7 +81,7 @@ func getServerListDirectory(c *gin.Context) {
return
}
stats, err := s.Filesystem.ListDirectory(d)
stats, err := s.Filesystem().ListDirectory(d)
if err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
@@ -126,7 +127,7 @@ func putServerRenameFiles(c *gin.Context) {
case <-ctx.Done():
return ctx.Err()
default:
if err := s.Filesystem.Rename(pf, pt); err != nil {
if err := s.Filesystem().Rename(pf, pt); err != nil {
// Return nil if the error is an is not exists.
// NOTE: os.IsNotExist() does not work if the error is wrapped.
if errors.Is(err, os.ErrNotExist) {
@@ -168,7 +169,7 @@ func postServerCopyFile(c *gin.Context) {
return
}
if err := s.Filesystem.Copy(data.Location); err != nil {
if err := s.Filesystem().Copy(data.Location); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
@@ -208,7 +209,7 @@ func postServerDeleteFiles(c *gin.Context) {
case <-ctx.Done():
return ctx.Err()
default:
return s.Filesystem.Delete(pi)
return s.Filesystem().Delete(pi)
}
})
}
@@ -232,28 +233,15 @@ func postServerWriteFile(c *gin.Context) {
}
f = "/" + strings.TrimLeft(f, "/")
// Check if there is enough space available to perform this action.
if err := s.Filesystem.HasSpaceFor(c.Request.ContentLength); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
if err := s.Filesystem.Writefile(f, c.Request.Body); err != nil {
if errors.Is(err, server.ErrIsDirectory) {
if err := s.Filesystem().Writefile(f, c.Request.Body); err != nil {
if errors.Is(err, filesystem.ErrIsDirectory) {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "Cannot write file, name conflicts with an existing directory by the same name.",
})
return
}
if strings.HasSuffix(err.Error(), "file name too long") {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "Cannot move or rename file, name is too long.",
})
return
}
TrackedServerError(err, s).AbortWithServerError(c)
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
@@ -273,7 +261,7 @@ func postServerCreateDirectory(c *gin.Context) {
return
}
if err := s.Filesystem.CreateDirectory(data.Name, data.Path); err != nil {
if err := s.Filesystem().CreateDirectory(data.Name, data.Path); err != nil {
if err.Error() == "not a directory" {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "Part of the path being created is not a directory (ENOTDIR).",
@@ -307,20 +295,20 @@ func postServerCompressFiles(c *gin.Context) {
return
}
if !s.Filesystem.HasSpaceAvailable(true) {
if !s.Filesystem().HasSpaceAvailable(true) {
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
"error": "This server does not have enough available disk space to generate a compressed archive.",
})
return
}
f, err := s.Filesystem.CompressFiles(data.RootPath, data.Files)
f, err := s.Filesystem().CompressFiles(data.RootPath, data.Files)
if err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
c.JSON(http.StatusOK, &server.Stat{
c.JSON(http.StatusOK, &filesystem.Stat{
Info: f,
Mimetype: "application/tar+gzip",
})
@@ -338,10 +326,10 @@ func postServerDecompressFiles(c *gin.Context) {
return
}
hasSpace, err := s.Filesystem.SpaceAvailableForDecompression(data.RootPath, data.File)
hasSpace, err := s.Filesystem().SpaceAvailableForDecompression(data.RootPath, data.File)
if err != nil {
// Handle an unknown format error.
if errors.Is(err, server.ErrUnknownArchiveFormat) {
if errors.Is(err, filesystem.ErrUnknownArchiveFormat) {
s.Log().WithField("error", err).Warn("failed to decompress file due to unknown format")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
@@ -361,7 +349,7 @@ func postServerDecompressFiles(c *gin.Context) {
return
}
if err := s.Filesystem.DecompressFile(data.RootPath, data.File); err != nil {
if err := s.Filesystem().DecompressFile(data.RootPath, data.File); err != nil {
if errors.Is(err, os.ErrNotExist) {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested archive was not found.",
@@ -426,13 +414,8 @@ func postServerUploadFiles(c *gin.Context) {
totalSize += header.Size
}
if err := s.Filesystem.HasSpaceFor(totalSize); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
for _, header := range headers {
p, err := s.Filesystem.SafePath(filepath.Join(directory, header.Filename))
p, err := s.Filesystem().SafePath(filepath.Join(directory, header.Filename))
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
@@ -454,7 +437,7 @@ func handleFileUpload(p string, s *server.Server, header *multipart.FileHeader)
}
defer file.Close()
if err := s.Filesystem.Writefile(p, file); err != nil {
if err := s.Filesystem().Writefile(p, file); err != nil {
return errors.WithStack(err)
}

View File

@@ -67,7 +67,7 @@ func getServerArchive(c *gin.Context) {
return
}
file, err := os.Open(s.Archiver.ArchivePath())
file, err := os.Open(s.Archiver.Path())
if err != nil {
tserr := TrackedServerError(err, s)
if !os.IsNotExist(err) {
@@ -84,7 +84,7 @@ func getServerArchive(c *gin.Context) {
c.Header("X-Checksum", checksum)
c.Header("X-Mime-Type", st.Mimetype)
c.Header("Content-Length", strconv.Itoa(int(st.Info.Size())))
c.Header("Content-Disposition", "attachment; filename="+s.Archiver.ArchiveName())
c.Header("Content-Disposition", "attachment; filename="+s.Archiver.Name())
c.Header("Content-Type", "application/octet-stream")
bufio.NewReader(file).WriteTo(c.Writer)
@@ -283,7 +283,7 @@ func postTransfer(c *gin.Context) {
}
// Un-archive the archive. That sounds weird..
if err := archiver.NewTarGz().Unarchive(archivePath, i.Server().Filesystem.Path()); err != nil {
if err := archiver.NewTarGz().Unarchive(archivePath, i.Server().Filesystem().Path()); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to extract server archive")
return
}

View File

@@ -14,6 +14,7 @@ import (
"github.com/pterodactyl/wings/environment/docker"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
"net/http"
"strings"
"sync"
@@ -193,7 +194,7 @@ func (h *Handler) SendErrorJson(msg Message, err error, shouldLog ...bool) error
j := h.GetJwt()
expected := errors.Is(err, server.ErrSuspended) ||
errors.Is(err, server.ErrIsRunning) ||
errors.Is(err, server.ErrNotEnoughDiskSpace)
errors.Is(err, filesystem.ErrNotEnoughDiskSpace)
message := "an unexpected error was encountered while handling this request"
if expected || (j != nil && j.HasPermission(PermissionReceiveErrors)) {
@@ -300,7 +301,7 @@ func (h *Handler) HandleInbound(m Message) error {
// Only send the current disk usage if the server is offline, if docker container is running,
// Environment#EnableResourcePolling() will send this data to all clients.
if state == environment.ProcessOfflineState {
_ = h.server.Filesystem.HasSpaceAvailable(false)
_ = h.server.Filesystem().HasSpaceAvailable(false)
b, _ := json.Marshal(h.server.Proc())
h.SendJson(&Message{