From 31ff3f8b568f3c8cc76ec07f07e12921f23bab65 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Thu, 15 Jul 2021 15:37:38 -0600 Subject: [PATCH] server(fs): keep file mode when extracting archive --- server/backup.go | 9 +++++++-- server/backup/backup.go | 6 ++++-- server/backup/backup_local.go | 10 +++++----- server/backup/backup_s3.go | 4 +++- server/filesystem/compress.go | 4 ++++ 5 files changed, 23 insertions(+), 10 deletions(-) diff --git a/server/backup.go b/server/backup.go index e94fa3e..ed85ace 100644 --- a/server/backup.go +++ b/server/backup.go @@ -2,12 +2,14 @@ package server import ( "io" + "io/fs" "io/ioutil" "os" "emperror.dev/errors" "github.com/apex/log" "github.com/docker/docker/client" + "github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/remote" "github.com/pterodactyl/wings/server/backup" @@ -150,9 +152,12 @@ func (s *Server) RestoreBackup(b backup.BackupInterface, reader io.ReadCloser) ( // Attempt to restore the backup to the server by running through each entry // in the file one at a time and writing them to the disk. s.Log().Debug("starting file writing process for backup restoration") - err = b.Restore(s.Context(), reader, func(file string, r io.Reader) error { + err = b.Restore(s.Context(), reader, func(file string, r io.Reader, mode fs.FileMode) error { s.Events().Publish(DaemonMessageEvent, "(restoring): "+file) - return s.Filesystem().Writefile(file, r) + if err := s.Filesystem().Writefile(file, r); err != nil { + return err + } + return s.Filesystem().Chmod(file, mode) }) return errors.WithStackIf(err) diff --git a/server/backup/backup.go b/server/backup/backup.go index a3408c7..92153f9 100644 --- a/server/backup/backup.go +++ b/server/backup/backup.go @@ -5,14 +5,16 @@ import ( "crypto/sha1" "encoding/hex" "io" + "io/fs" "os" "path" "emperror.dev/errors" "github.com/apex/log" + "golang.org/x/sync/errgroup" + "github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/remote" - "golang.org/x/sync/errgroup" ) type AdapterType string @@ -24,7 +26,7 @@ const ( // RestoreCallback is a generic restoration callback that exists for both local // and remote backups allowing the files to be restored. -type RestoreCallback func(file string, r io.Reader) error +type RestoreCallback func(file string, r io.Reader, mode fs.FileMode) error // noinspection GoNameStartsWithPackageName type BackupInterface interface { diff --git a/server/backup/backup_local.go b/server/backup/backup_local.go index 68a6603..71b1242 100644 --- a/server/backup/backup_local.go +++ b/server/backup/backup_local.go @@ -6,9 +6,11 @@ import ( "os" "emperror.dev/errors" + "github.com/pterodactyl/wings/server/filesystem" "github.com/mholt/archiver/v3" + "github.com/pterodactyl/wings/remote" ) @@ -85,12 +87,10 @@ func (b *LocalBackup) Restore(ctx context.Context, _ io.Reader, callback Restore // Stop walking if the context is canceled. return archiver.ErrStopWalk default: - { - if f.IsDir() { - return nil - } - return callback(filesystem.ExtractNameFromArchive(f), f) + if f.IsDir() { + return nil } + return callback(filesystem.ExtractNameFromArchive(f), f, f.Mode()) } }) } diff --git a/server/backup/backup_s3.go b/server/backup/backup_s3.go index 02ec13f..e240b5e 100644 --- a/server/backup/backup_s3.go +++ b/server/backup/backup_s3.go @@ -13,9 +13,11 @@ import ( "emperror.dev/errors" "github.com/cenkalti/backoff/v4" + "github.com/pterodactyl/wings/server/filesystem" "github.com/juju/ratelimit" + "github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/remote" ) @@ -114,7 +116,7 @@ func (s *S3Backup) Restore(ctx context.Context, r io.Reader, callback RestoreCal return err } if header.Typeflag == tar.TypeReg { - if err := callback(header.Name, tr); err != nil { + if err := callback(header.Name, tr, header.FileInfo().Mode()); err != nil { return err } } diff --git a/server/filesystem/compress.go b/server/filesystem/compress.go index 23e805d..5227512 100644 --- a/server/filesystem/compress.go +++ b/server/filesystem/compress.go @@ -132,6 +132,10 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error { if err := fs.Writefile(p, f); err != nil { return wrapError(err, source) } + // Update the file permissions to the one set in the archive. + if err := fs.Chmod(p, f.Mode()); err != nil { + return wrapError(err, source) + } return nil }) if err != nil {