From de30e2fcc9d24f88cb9812dcf4f789db83bb94cf Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 27 Sep 2020 11:16:38 -0700 Subject: [PATCH] Dont attempt to get size within archive process, will return empty; ref pterodactyl/panel#2420 The stat call is operating against an unflushed file if called in the archive function, so you'll just get the emtpy archive size, rather than the final size. Plus, we only used the file stat in one place, so slight efficiency win? --- router/router_server_files.go | 19 +------------------ server/backup/archiver.go | 13 ++++--------- server/backup/backup_local.go | 2 +- server/backup/backup_s3.go | 2 +- server/filesystem.go | 16 ++++++++++++++-- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/router/router_server_files.go b/router/router_server_files.go index bd9dd03..341ba2e 100644 --- a/router/router_server_files.go +++ b/router/router_server_files.go @@ -170,6 +170,7 @@ func postServerCopyFile(c *gin.Context) { if err := s.Filesystem.Copy(data.Location); err != nil { TrackedServerError(err, s).AbortFilesystemError(c) + return } c.Status(http.StatusNoContent) @@ -313,30 +314,12 @@ func postServerCompressFiles(c *gin.Context) { return } - d, err := s.Filesystem.SafePath(data.RootPath) - if err != nil { - TrackedServerError(err, s).AbortWithServerError(c) - return - } - f, err := s.Filesystem.CompressFiles(data.RootPath, data.Files) if err != nil { TrackedServerError(err, s).AbortFilesystemError(c) return } - if err := s.Filesystem.HasSpaceFor(f.Size()); err != nil { - if errors.Is(err, server.ErrNotEnoughDiskSpace) { - // Exceeding space limits, delete archive and return error. Kind of a waste of resources - // I suppose, but oh well. - _ = os.Remove(filepath.Join(d, f.Name())) - } - - TrackedServerError(err, s).AbortFilesystemError(c) - return - } - - c.JSON(http.StatusOK, &server.Stat{ Info: f, Mimetype: "application/tar+gzip", diff --git a/server/backup/archiver.go b/server/backup/archiver.go index 7f7668b..4dedccb 100644 --- a/server/backup/archiver.go +++ b/server/backup/archiver.go @@ -23,10 +23,10 @@ type Archive struct { } // Creates an archive at dst with all of the files defined in the included files struct. -func (a *Archive) Create(dst string, ctx context.Context) (os.FileInfo, error) { +func (a *Archive) Create(dst string, ctx context.Context) error { f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { - return nil, errors.WithStack(err) + return errors.WithStack(err) } defer f.Close() @@ -75,15 +75,10 @@ func (a *Archive) Create(dst string, ctx context.Context) (os.FileInfo, error) { log.WithField("location", dst).Warn("failed to delete corrupted backup archive") } - return nil, errors.WithStack(err) + return errors.WithStack(err) } - st, err := f.Stat() - if err != nil { - return nil, errors.WithStack(err) - } - - return st, nil + return nil } // Adds a single file to the existing tar archive writer. diff --git a/server/backup/backup_local.go b/server/backup/backup_local.go index 5990385..bc07bfe 100644 --- a/server/backup/backup_local.go +++ b/server/backup/backup_local.go @@ -47,7 +47,7 @@ func (b *LocalBackup) Generate(included *IncludedFiles, prefix string) (*Archive Files: included, } - if _, err := a.Create(b.Path(), context.Background()); err != nil { + if err := a.Create(b.Path(), context.Background()); err != nil { return nil, errors.WithStack(err) } diff --git a/server/backup/backup_s3.go b/server/backup/backup_s3.go index 6c789c9..55bd904 100644 --- a/server/backup/backup_s3.go +++ b/server/backup/backup_s3.go @@ -33,7 +33,7 @@ func (s *S3Backup) Generate(included *IncludedFiles, prefix string) (*ArchiveDet Files: included, } - if _, err := a.Create(s.Path(), context.Background()); err != nil { + if err := a.Create(s.Path(), context.Background()); err != nil { return nil, errors.WithStack(err) } diff --git a/server/filesystem.go b/server/filesystem.go index 769401b..5192d1e 100644 --- a/server/filesystem.go +++ b/server/filesystem.go @@ -956,11 +956,23 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er a := &backup.Archive{TrimPrefix: fs.Path(), Files: inc} d := path.Join(cleanedRootDir, fmt.Sprintf("archive-%s.tar.gz", strings.ReplaceAll(time.Now().Format(time.RFC3339), ":", ""))) - f, err := a.Create(d, context.Background()) - if err != nil { + if err := a.Create(d, context.Background()); err != nil { return nil, errors.WithStack(err) } + f, err := os.Stat(d) + if err != nil { + _ = os.Remove(d) + + return nil, err + } + + if err := fs.HasSpaceFor(f.Size()); err != nil { + _ = os.Remove(d) + + return nil, err + } + atomic.AddInt64(&fs.disk, f.Size()) return f, nil