Compare commits
1 Commits
release/v1
...
release/v1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
954186291f |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -1,15 +1,5 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## v1.11.11
|
|
||||||
### Fixed
|
|
||||||
* Backups missing content when a `.pteroignore` file is used
|
|
||||||
* Archives originating from a subdirectory not containing any files ([#5030](https://github.com/pterodactyl/panel/issues/5030))
|
|
||||||
|
|
||||||
## v1.11.10
|
|
||||||
### Fixed
|
|
||||||
* Archives randomly ignoring files and directories ([#5027](https://github.com/pterodactyl/panel/issues/5027))
|
|
||||||
* Crash when deleting or transferring a server ([#5028](https://github.com/pterodactyl/panel/issues/5028))
|
|
||||||
|
|
||||||
## v1.11.9
|
## v1.11.9
|
||||||
### Changed
|
### Changed
|
||||||
* Release binaries are now built with Go 1.21.8
|
* Release binaries are now built with Go 1.21.8
|
||||||
|
|||||||
85
flake.lock
generated
85
flake.lock
generated
@@ -1,85 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": {
|
|
||||||
"flake-parts": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs-lib": "nixpkgs-lib"
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1706830856,
|
|
||||||
"narHash": "sha256-a0NYyp+h9hlb7ddVz4LUn1vT/PLwqfrWYcHMvFB1xYg=",
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"rev": "b253292d9c0a5ead9bc98c4e9a26c6312e27d69f",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "hercules-ci",
|
|
||||||
"repo": "flake-parts",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1707956935,
|
|
||||||
"narHash": "sha256-ZL2TrjVsiFNKOYwYQozpbvQSwvtV/3Me7Zwhmdsfyu4=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "a4d4fe8c5002202493e87ec8dbc91335ff55552c",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-lib": {
|
|
||||||
"locked": {
|
|
||||||
"dir": "lib",
|
|
||||||
"lastModified": 1706550542,
|
|
||||||
"narHash": "sha256-UcsnCG6wx++23yeER4Hg18CXWbgNpqNXcHIo5/1Y+hc=",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"rev": "97b17f32362e475016f942bbdfda4a4a72a8a652",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"dir": "lib",
|
|
||||||
"owner": "NixOS",
|
|
||||||
"ref": "nixos-unstable",
|
|
||||||
"repo": "nixpkgs",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": {
|
|
||||||
"inputs": {
|
|
||||||
"flake-parts": "flake-parts",
|
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"treefmt-nix": "treefmt-nix"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"treefmt-nix": {
|
|
||||||
"inputs": {
|
|
||||||
"nixpkgs": [
|
|
||||||
"nixpkgs"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 1707300477,
|
|
||||||
"narHash": "sha256-qQF0fEkHlnxHcrKIMRzOETnRBksUK048MXkX0SOmxvA=",
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"rev": "ac599dab59a66304eb511af07b3883114f061b9d",
|
|
||||||
"type": "github"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"owner": "numtide",
|
|
||||||
"repo": "treefmt-nix",
|
|
||||||
"type": "github"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"root": "root",
|
|
||||||
"version": 7
|
|
||||||
}
|
|
||||||
54
flake.nix
54
flake.nix
@@ -1,54 +0,0 @@
|
|||||||
{
|
|
||||||
description = "Wings";
|
|
||||||
|
|
||||||
inputs = {
|
|
||||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
||||||
|
|
||||||
treefmt-nix = {
|
|
||||||
url = "github:numtide/treefmt-nix";
|
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
outputs = {...} @ inputs:
|
|
||||||
inputs.flake-parts.lib.mkFlake {inherit inputs;} {
|
|
||||||
systems = ["aarch64-darwin" "aarch64-linux" "x86_64-darwin" "x86_64-linux"];
|
|
||||||
|
|
||||||
imports = [
|
|
||||||
inputs.treefmt-nix.flakeModule
|
|
||||||
];
|
|
||||||
|
|
||||||
perSystem = {system, ...}: let
|
|
||||||
pkgs = import inputs.nixpkgs {inherit system;};
|
|
||||||
in {
|
|
||||||
devShells.default = pkgs.mkShell {
|
|
||||||
buildInputs = with pkgs; [
|
|
||||||
go_1_22
|
|
||||||
gofumpt
|
|
||||||
golangci-lint
|
|
||||||
gotools
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
treefmt = {
|
|
||||||
projectRootFile = "flake.nix";
|
|
||||||
|
|
||||||
programs = {
|
|
||||||
alejandra.enable = true;
|
|
||||||
deadnix.enable = true;
|
|
||||||
gofumpt = {
|
|
||||||
enable = true;
|
|
||||||
extra = true;
|
|
||||||
};
|
|
||||||
shellcheck.enable = true;
|
|
||||||
shfmt = {
|
|
||||||
enable = true;
|
|
||||||
indent_size = 0; # 0 causes shfmt to use tabs
|
|
||||||
};
|
|
||||||
yamlfmt.enable = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -66,13 +66,6 @@ func (fs *UnixFS) walkDir(b []byte, parentfd int, name, relative string, d DirEn
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, d1 := range dirs {
|
for _, d1 := range dirs {
|
||||||
// TODO: the path.Join on this line may actually be partially incorrect.
|
|
||||||
// If we are not walking starting at the root, relative will contain the
|
|
||||||
// name of the directory we are starting the walk from, which will be
|
|
||||||
// relative to the root of the filesystem instead of from where the walk
|
|
||||||
// was initiated from.
|
|
||||||
//
|
|
||||||
// ref; https://github.com/pterodactyl/panel/issues/5030
|
|
||||||
if err := fs.walkDir(b, dirfd, d1.Name(), path.Join(relative, d1.Name()), d1, walkDirFn); err != nil {
|
if err := fs.walkDir(b, dirfd, d1.Name(), path.Join(relative, d1.Name()), d1, walkDirFn); err != nil {
|
||||||
if err == SkipDir {
|
if err == SkipDir {
|
||||||
break
|
break
|
||||||
|
|||||||
@@ -227,19 +227,20 @@ func deleteServer(c *gin.Context) {
|
|||||||
//
|
//
|
||||||
// In addition, servers with large amounts of files can take some time to finish deleting,
|
// In addition, servers with large amounts of files can take some time to finish deleting,
|
||||||
// so we don't want to block the HTTP call while waiting on this.
|
// so we don't want to block the HTTP call while waiting on this.
|
||||||
go func(s *server.Server) {
|
go func(p string) {
|
||||||
fs := s.Filesystem()
|
_ = s.Filesystem().UnixFS().Close()
|
||||||
p := fs.Path()
|
|
||||||
_ = fs.UnixFS().Close()
|
|
||||||
if err := os.RemoveAll(p); err != nil {
|
if err := os.RemoveAll(p); err != nil {
|
||||||
log.WithFields(log.Fields{"path": p, "error": err}).Warn("failed to remove server files during deletion process")
|
log.WithFields(log.Fields{"path": p, "error": err}).Warn("failed to remove server files during deletion process")
|
||||||
}
|
}
|
||||||
}(s)
|
}(s.Filesystem().Path())
|
||||||
|
|
||||||
middleware.ExtractManager(c).Remove(func(server *server.Server) bool {
|
middleware.ExtractManager(c).Remove(func(server *server.Server) bool {
|
||||||
return server.ID() == s.ID()
|
return server.ID() == s.ID()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Deallocate the reference to this server.
|
||||||
|
s = nil
|
||||||
|
|
||||||
c.Status(http.StatusNoContent)
|
c.Status(http.StatusNoContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,9 +66,10 @@ type Archive struct {
|
|||||||
// BaseDirectory .
|
// BaseDirectory .
|
||||||
BaseDirectory string
|
BaseDirectory string
|
||||||
|
|
||||||
// Files specifies the files to archive, this takes priority over the Ignore
|
// Files specifies the files to archive, this takes priority over the Ignore option, if
|
||||||
// option, if unspecified, all files in the BaseDirectory will be archived
|
// unspecified, all files in the BasePath will be archived unless Ignore is set.
|
||||||
// unless Ignore is set.
|
//
|
||||||
|
// All items in Files must be absolute within BasePath.
|
||||||
Files []string
|
Files []string
|
||||||
|
|
||||||
// Progress wraps the writer of the archive to pass through the progress tracker.
|
// Progress wraps the writer of the archive to pass through the progress tracker.
|
||||||
@@ -113,20 +114,11 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||||||
return errors.New("filesystem: archive.Filesystem is unset")
|
return errors.New("filesystem: archive.Filesystem is unset")
|
||||||
}
|
}
|
||||||
|
|
||||||
// The base directory may come with a prefixed `/`, strip it to prevent
|
for i, f := range a.Files {
|
||||||
// problems.
|
if !strings.HasPrefix(f, a.Filesystem.Path()) {
|
||||||
a.BaseDirectory = strings.TrimPrefix(a.BaseDirectory, "/")
|
continue
|
||||||
|
|
||||||
if filesLen := len(a.Files); filesLen > 0 {
|
|
||||||
files := make([]string, filesLen)
|
|
||||||
for i, f := range a.Files {
|
|
||||||
if !strings.HasPrefix(f, a.Filesystem.Path()) {
|
|
||||||
files[i] = f
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
files[i] = strings.TrimPrefix(strings.TrimPrefix(f, a.Filesystem.Path()), "/")
|
|
||||||
}
|
}
|
||||||
a.Files = files
|
a.Files[i] = strings.TrimPrefix(strings.TrimPrefix(f, a.Filesystem.Path()), "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose which compression level to use based on the compression_level configuration option
|
// Choose which compression level to use based on the compression_level configuration option
|
||||||
@@ -136,6 +128,8 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||||||
compressionLevel = pgzip.NoCompression
|
compressionLevel = pgzip.NoCompression
|
||||||
case "best_compression":
|
case "best_compression":
|
||||||
compressionLevel = pgzip.BestCompression
|
compressionLevel = pgzip.BestCompression
|
||||||
|
case "best_speed":
|
||||||
|
fallthrough
|
||||||
default:
|
default:
|
||||||
compressionLevel = pgzip.BestSpeed
|
compressionLevel = pgzip.BestSpeed
|
||||||
}
|
}
|
||||||
@@ -161,7 +155,7 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||||||
i := ignore.CompileIgnoreLines(strings.Split(a.Ignore, "\n")...)
|
i := ignore.CompileIgnoreLines(strings.Split(a.Ignore, "\n")...)
|
||||||
callback = a.callback(func(_ int, _, relative string, _ ufs.DirEntry) error {
|
callback = a.callback(func(_ int, _, relative string, _ ufs.DirEntry) error {
|
||||||
if i.MatchesPath(relative) {
|
if i.MatchesPath(relative) {
|
||||||
return SkipThis
|
return ufs.SkipDir
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
@@ -171,14 +165,11 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||||||
callback = a.callback()
|
callback = a.callback()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the base directory we were provided.
|
|
||||||
dirfd, name, closeFd, err := fs.SafePath(a.BaseDirectory)
|
dirfd, name, closeFd, err := fs.SafePath(a.BaseDirectory)
|
||||||
defer closeFd()
|
defer closeFd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively walk the base directory.
|
|
||||||
return fs.WalkDirat(dirfd, name, func(dirfd int, name, relative string, d ufs.DirEntry, err error) error {
|
return fs.WalkDirat(dirfd, name, func(dirfd int, name, relative string, d ufs.DirEntry, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -195,35 +186,16 @@ func (a *Archive) Stream(ctx context.Context, w io.Writer) error {
|
|||||||
// Callback function used to determine if a given file should be included in the archive
|
// Callback function used to determine if a given file should be included in the archive
|
||||||
// being generated.
|
// being generated.
|
||||||
func (a *Archive) callback(opts ...walkFunc) walkFunc {
|
func (a *Archive) callback(opts ...walkFunc) walkFunc {
|
||||||
// Get the base directory we need to strip when walking.
|
|
||||||
//
|
|
||||||
// This is important as when we are walking, the last part of the base directory
|
|
||||||
// is present on all the paths we walk.
|
|
||||||
var base string
|
|
||||||
if a.BaseDirectory != "" {
|
|
||||||
base = filepath.Base(a.BaseDirectory) + "/"
|
|
||||||
}
|
|
||||||
return func(dirfd int, name, relative string, d ufs.DirEntry) error {
|
return func(dirfd int, name, relative string, d ufs.DirEntry) error {
|
||||||
// Skip directories because we are walking them recursively.
|
// Skip directories because we are walking them recursively.
|
||||||
if d.IsDir() {
|
if d.IsDir() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// If base isn't empty, strip it from the relative path. This fixes an
|
|
||||||
// issue when creating an archive starting from a nested directory.
|
|
||||||
//
|
|
||||||
// See https://github.com/pterodactyl/panel/issues/5030 for more details.
|
|
||||||
if base != "" {
|
|
||||||
relative = strings.TrimPrefix(relative, base)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the additional options passed to this callback function. If any of them return
|
// Call the additional options passed to this callback function. If any of them return
|
||||||
// a non-nil error we will exit immediately.
|
// a non-nil error we will exit immediately.
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
if err := opt(dirfd, name, relative, d); err != nil {
|
if err := opt(dirfd, name, relative, d); err != nil {
|
||||||
if err == SkipThis {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -234,8 +206,6 @@ func (a *Archive) callback(opts ...walkFunc) walkFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var SkipThis = errors.New("skip this")
|
|
||||||
|
|
||||||
// Pushes only files defined in the Files key to the final archive.
|
// Pushes only files defined in the Files key to the final archive.
|
||||||
func (a *Archive) withFilesCallback() walkFunc {
|
func (a *Archive) withFilesCallback() walkFunc {
|
||||||
return a.callback(func(_ int, _, relative string, _ ufs.DirEntry) error {
|
return a.callback(func(_ int, _, relative string, _ ufs.DirEntry) error {
|
||||||
@@ -255,7 +225,7 @@ func (a *Archive) withFilesCallback() walkFunc {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return SkipThis
|
return ufs.SkipDir
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,9 @@ import (
|
|||||||
"github.com/pterodactyl/wings/internal/ufs"
|
"github.com/pterodactyl/wings/internal/ufs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: detect and enable
|
||||||
|
var useOpenat2 = true
|
||||||
|
|
||||||
type Filesystem struct {
|
type Filesystem struct {
|
||||||
unixFS *ufs.Quota
|
unixFS *ufs.Quota
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
package system
|
package system
|
||||||
|
|
||||||
var Version = "1.11.11"
|
var Version = "1.11.9"
|
||||||
|
|||||||
Reference in New Issue
Block a user