Replace error handling package with emperror; add better reporting for errors escaping server root

This commit is contained in:
Dane Everitt 2020-11-08 13:52:20 -08:00
parent 0989c78d4b
commit be9d1a3986
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
55 changed files with 396 additions and 367 deletions

View File

@ -2,10 +2,10 @@ package api
import (
"bytes"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"io"
@ -69,7 +69,7 @@ func (r *Request) Endpoint(endpoint string) string {
func (r *Request) Make(method, url string, body io.Reader, opts ...func(r *http.Request)) (*Response, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
req.Header.Set("User-Agent", fmt.Sprintf("Pterodactyl Wings/v%s (id:%s)", system.Version, config.Get().AuthenticationTokenId))
@ -127,7 +127,7 @@ func (r *Request) Get(url string, data Q) (*Response, error) {
func (r *Request) Post(url string, data interface{}) (*Response, error) {
b, err := json.Marshal(data)
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return r.Make(http.MethodPost, r.Endpoint(url), bytes.NewBuffer(b))
@ -167,10 +167,10 @@ func (r *Response) Read() ([]byte, error) {
func (r *Response) Bind(v interface{}) error {
b, err := r.Read()
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.WithStack(json.Unmarshal(b, &v))
return errors.WithStackIf(json.Unmarshal(b, &v))
}
// Returns the error message from the API call as a string. The error message will be formatted

View File

@ -1,8 +1,8 @@
package api
import (
"emperror.dev/errors"
"fmt"
"github.com/pkg/errors"
"strconv"
)
@ -16,7 +16,7 @@ type BackupRemoteUploadResponse struct {
func (r *Request) GetBackupRemoteUploadURLs(backup string, size int64) (*BackupRemoteUploadResponse, error) {
resp, err := r.Get(fmt.Sprintf("/backups/%s", backup), Q{"size": strconv.FormatInt(size, 10)})
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -26,7 +26,7 @@ func (r *Request) GetBackupRemoteUploadURLs(backup string, size int64) (*BackupR
var res BackupRemoteUploadResponse
if err := resp.Bind(&res); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return &res, nil
@ -44,7 +44,7 @@ type BackupRequest struct {
func (r *Request) SendBackupStatus(backup string, data BackupRequest) error {
resp, err := r.Post(fmt.Sprintf("/backups/%s", backup), data)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer resp.Body.Close()

View File

@ -2,10 +2,10 @@ package api
import (
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"golang.org/x/sync/errgroup"
"strconv"
@ -57,7 +57,7 @@ type RawServerData struct {
func (r *Request) GetServers() ([]RawServerData, error) {
resp, err := r.Get("/servers", Q{"per_page": strconv.Itoa(int(config.Get().RemoteQuery.BootServersPerPage))})
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -67,7 +67,7 @@ func (r *Request) GetServers() ([]RawServerData, error) {
var res allServerResponse
if err := resp.Bind(&res); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
var mu sync.Mutex
@ -117,7 +117,7 @@ func (r *Request) GetServers() ([]RawServerData, error) {
}
if err := g.Wait(); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
}
@ -130,7 +130,7 @@ func (r *Request) GetServerConfiguration(uuid string) (ServerConfigurationRespon
resp, err := r.Get(fmt.Sprintf("/servers/%s", uuid), nil)
if err != nil {
return cfg, errors.WithStack(err)
return cfg, errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -139,7 +139,7 @@ func (r *Request) GetServerConfiguration(uuid string) (ServerConfigurationRespon
}
if err := resp.Bind(&cfg); err != nil {
return cfg, errors.WithStack(err)
return cfg, errors.WithStackIf(err)
}
return cfg, nil
@ -150,7 +150,7 @@ func (r *Request) GetInstallationScript(uuid string) (InstallationScript, error)
var is InstallationScript
resp, err := r.Get(fmt.Sprintf("/servers/%s/install", uuid), nil)
if err != nil {
return is, errors.WithStack(err)
return is, errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -159,7 +159,7 @@ func (r *Request) GetInstallationScript(uuid string) (InstallationScript, error)
}
if err := resp.Bind(&is); err != nil {
return is, errors.WithStack(err)
return is, errors.WithStackIf(err)
}
return is, nil
@ -169,7 +169,7 @@ func (r *Request) GetInstallationScript(uuid string) (InstallationScript, error)
func (r *Request) SendInstallationStatus(uuid string, successful bool) error {
resp, err := r.Post(fmt.Sprintf("/servers/%s/install", uuid), D{"successful": successful})
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -183,7 +183,7 @@ func (r *Request) SendInstallationStatus(uuid string, successful bool) error {
func (r *Request) SendArchiveStatus(uuid string, successful bool) error {
resp, err := r.Post(fmt.Sprintf("/servers/%s/archive", uuid), D{"successful": successful})
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -193,7 +193,7 @@ func (r *Request) SendArchiveStatus(uuid string, successful bool) error {
func (r *Request) SendTransferFailure(uuid string) error {
resp, err := r.Get(fmt.Sprintf("/servers/%s/transfer/failure", uuid), nil)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer resp.Body.Close()
@ -203,7 +203,7 @@ func (r *Request) SendTransferFailure(uuid string) error {
func (r *Request) SendTransferSuccess(uuid string) error {
resp, err := r.Get(fmt.Sprintf("/servers/%s/transfer/success", uuid), nil)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer resp.Body.Close()

View File

@ -1,8 +1,8 @@
package api
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pkg/errors"
"regexp"
)

View File

@ -19,7 +19,7 @@ import (
"github.com/pterodactyl/wings/loggers/cli"
"golang.org/x/crypto/acme/autocert"
"github.com/pkg/errors"
"emperror.dev/errors"
"github.com/pkg/profile"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -77,7 +77,7 @@ func readConfiguration() (*config.Configuration, error) {
}
if s, err := os.Stat(p); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
} else if s.IsDir() {
return nil, errors.New("cannot use directory as configuration file path")
}
@ -199,7 +199,7 @@ func rootCmdRun(*cobra.Command, []string) {
states, err := server.CachedServerStates()
if err != nil {
log.WithField("error", errors.WithStack(err)).Error("failed to retrieve locally cached server states from disk, assuming all servers in offline state")
log.WithField("error", errors.WithStackIf(err)).Error("failed to retrieve locally cached server states from disk, assuming all servers in offline state")
}
// Create a new workerpool that limits us to 4 servers being bootstrapped at a time
@ -235,7 +235,7 @@ func rootCmdRun(*cobra.Command, []string) {
// as a result will result in a slow boot.
if !r && (st == environment.ProcessRunningState || st == environment.ProcessStartingState) {
if err := s.HandlePowerAction(server.PowerActionStart); err != nil {
s.Log().WithField("error", errors.WithStack(err)).Warn("failed to return server to running state")
s.Log().WithField("error", errors.WithStackIf(err)).Warn("failed to return server to running state")
}
} else if r || (!r && s.IsRunning()) {
// If the server is currently running on Docker, mark the process as being in that state.
@ -248,7 +248,7 @@ func rootCmdRun(*cobra.Command, []string) {
s.Environment.SetState(environment.ProcessRunningState)
if err := s.Environment.Attach(); err != nil {
s.Log().WithField("error", errors.WithStack(err)).Warn("failed to attach to running server environment")
s.Log().WithField("error", errors.WithStackIf(err)).Warn("failed to attach to running server environment")
}
return
@ -369,13 +369,13 @@ func Execute() error {
// in the code without having to pass around a logger instance.
func configureLogging(logDir string, debug bool) error {
if err := os.MkdirAll(path.Join(logDir, "/install"), 0700); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
p := filepath.Join(logDir, "/wings.log")
w, err := logrotate.NewFile(p)
if err != nil {
panic(errors.Wrap(err, "failed to open process log file"))
panic(errors.WrapIf(err, "failed to open process log file"))
}
if debug {

View File

@ -1,11 +1,11 @@
package config
import (
"emperror.dev/errors"
"fmt"
"github.com/cobaugh/osrelease"
"github.com/creasty/defaults"
"github.com/gbrlsnchs/jwt/v3"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"io/ioutil"
"os"
@ -198,7 +198,7 @@ func GetJwtAlgorithm() *jwt.HMACSHA {
func NewFromPath(path string) (*Configuration, error) {
c := new(Configuration)
if err := defaults.Set(c); err != nil {
return c, errors.WithStack(err)
return c, errors.WithStackIf(err)
}
c.unsafeSetPath(path)
@ -236,12 +236,12 @@ func (c *Configuration) EnsurePterodactylUser() (*user.User, error) {
if err == nil {
return u, c.setSystemUser(u)
} else if _, ok := err.(user.UnknownUserError); !ok {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
sysName, err := getSystemName()
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
var command = fmt.Sprintf("useradd --system --no-create-home --shell /bin/false %s", c.System.Username)
@ -254,17 +254,17 @@ func (c *Configuration) EnsurePterodactylUser() (*user.User, error) {
// We have to create the group first on Alpine, so do that here before continuing on
// to the user creation process.
if _, err := exec.Command("addgroup", "-S", c.System.Username).Output(); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
}
split := strings.Split(command, " ")
if _, err := exec.Command(split[0], split[1:]...).Output(); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
if u, err := user.Lookup(c.System.Username); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
} else {
return u, c.setSystemUser(u)
}
@ -306,11 +306,11 @@ func (c *Configuration) WriteToDisk() error {
b, err := yaml.Marshal(&ccopy)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err := ioutil.WriteFile(c.GetPath(), b, 0644); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -320,7 +320,7 @@ func (c *Configuration) WriteToDisk() error {
func getSystemName() (string, error) {
// use osrelease to get release version and ID
if release, err := osrelease.Read(); err != nil {
return "", errors.WithStack(err)
return "", errors.WithStackIf(err)
} else {
return release["ID"], nil
}

View File

@ -1,10 +1,10 @@
package config
import (
"emperror.dev/errors"
"encoding/base64"
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
)
type dockerNetworkInterfaces struct {
@ -73,7 +73,7 @@ func (c RegistryConfiguration) Base64() (string, error) {
b, err := json.Marshal(authConfig)
if err != nil {
return "", errors.WithStack(err)
return "", errors.WithStackIf(err)
}
return base64.URLEncoding.EncodeToString(b), nil

View File

@ -2,9 +2,9 @@ package config
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"html/template"
"io/ioutil"
"os"
@ -94,7 +94,7 @@ func (sc *SystemConfiguration) ConfigureDirectories() error {
// that.
if d, err := filepath.EvalSymlinks(sc.Data); err != nil {
if !os.IsNotExist(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else if d != sc.Data {
sc.Data = d
@ -130,13 +130,13 @@ func (sc *SystemConfiguration) EnableLogRotation() error {
}
if st, err := os.Stat("/etc/logrotate.d"); err != nil && !os.IsNotExist(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
} else if (err != nil && os.IsNotExist(err)) || !st.IsDir() {
return nil
}
if _, err := os.Stat("/etc/logrotate.d/wings"); err != nil && !os.IsNotExist(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
} else if err == nil {
return nil
}
@ -147,7 +147,7 @@ func (sc *SystemConfiguration) EnableLogRotation() error {
// it so files can be rotated easily.
f, err := os.Create("/etc/logrotate.d/wings")
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer f.Close()
@ -167,10 +167,10 @@ func (sc *SystemConfiguration) EnableLogRotation() error {
}`)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.Wrap(t.Execute(f, sc), "failed to write logrotate file to disk")
return errors.WrapIf(t.Execute(f, sc), "failed to write logrotate file to disk")
}
// Returns the location of the JSON file that tracks server states.
@ -190,7 +190,7 @@ func (sc *SystemConfiguration) ConfigureTimezone() error {
if sc.Timezone == "" {
if b, err := ioutil.ReadFile("/etc/timezone"); err != nil {
if !os.IsNotExist(err) {
return errors.Wrap(err, "failed to open /etc/timezone for automatic server timezone calibration")
return errors.WrapIf(err, "failed to open /etc/timezone for automatic server timezone calibration")
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
@ -224,5 +224,5 @@ func (sc *SystemConfiguration) ConfigureTimezone() error {
_, err := time.LoadLocation(sc.Timezone)
return errors.Wrap(err, fmt.Sprintf("the supplied timezone %s is invalid", sc.Timezone))
return errors.WrapIf(err, fmt.Sprintf("the supplied timezone %s is invalid", sc.Timezone))
}

View File

@ -4,6 +4,7 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
@ -12,7 +13,6 @@ import (
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/client"
"github.com/docker/docker/daemon/logger/jsonfilelog"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"io"
@ -36,7 +36,7 @@ func (e *Environment) Attach() error {
}
if err := e.followOutput(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
opts := types.ContainerAttachOptions{
@ -48,7 +48,7 @@ func (e *Environment) Attach() error {
// Set the stream again with the container.
if st, err := e.client.ContainerAttach(context.Background(), e.Id, opts); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
} else {
e.SetStream(&st)
}
@ -70,14 +70,14 @@ func (e *Environment) Attach() error {
// indicates that the container is no longer running.
go func(ctx context.Context) {
if err := e.pollResources(ctx); err != nil {
log.WithField("environment_id", e.Id).WithField("error", errors.WithStack(err)).Error("error during environment resource polling")
log.WithField("environment_id", e.Id).WithField("error", errors.WithStackIf(err)).Error("error during environment resource polling")
}
}(ctx)
// Stream the reader output to the console which will then fire off events and handle console
// throttling and sending the output to the user.
if _, err := io.Copy(console, e.stream.Reader); err != nil {
log.WithField("environment_id", e.Id).WithField("error", errors.WithStack(err)).Error("error while copying environment output to console")
log.WithField("environment_id", e.Id).WithField("error", errors.WithStackIf(err)).Error("error while copying environment output to console")
}
}(c)
@ -115,7 +115,7 @@ func (e *Environment) InSituUpdate() error {
return nil
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
u := container.UpdateConfig{
@ -125,7 +125,7 @@ func (e *Environment) InSituUpdate() error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
if _, err := e.client.ContainerUpdate(ctx, e.Id, u); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -140,12 +140,12 @@ func (e *Environment) Create() error {
if _, err := e.client.ContainerInspect(context.Background(), e.Id); err == nil {
return nil
} else if !client.IsErrNotFound(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Try to pull the requested image before creating the container.
if err := e.ensureImageExists(e.meta.Image); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
a := e.Configuration.Allocations()
@ -220,7 +220,7 @@ func (e *Environment) Create() error {
}
if _, err := e.client.ContainerCreate(context.Background(), conf, hostConf, nil, e.Id); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -272,7 +272,7 @@ func (e *Environment) Destroy() error {
func (e *Environment) followOutput() error {
if exists, err := e.Exists(); !exists {
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.New(fmt.Sprintf("no such container: %s", e.Id))
@ -338,7 +338,7 @@ func (e *Environment) followOutput() error {
}
}(reader)
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Pulls the image from Docker. If there is an error while pulling the image from the source

View File

@ -2,9 +2,9 @@ package docker
import (
"context"
"emperror.dev/errors"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/events"
@ -156,7 +156,7 @@ func (e *Environment) ExitState() (uint32, bool, error) {
return 1, false, nil
}
return 0, false, errors.WithStack(err)
return 0, false, errors.WithStackIf(err)
}
return uint32(c.State.ExitCode), c.State.OOMKilled, nil

View File

@ -2,11 +2,11 @@ package docker
import (
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/environment"
"os"
@ -26,7 +26,7 @@ func (e *Environment) OnBeforeStart() error {
// the Panel is usee.
if err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{RemoveVolumes: true}); err != nil {
if !client.IsErrNotFound(err) {
return errors.Wrap(err, "failed to remove server docker container during pre-boot")
return errors.WrapIf(err, "failed to remove server docker container during pre-boot")
}
}
@ -69,7 +69,7 @@ func (e *Environment) Start() error {
//
// @see https://github.com/pterodactyl/panel/issues/2000
if !client.IsErrNotFound(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else {
// If the server is running update our internal state and continue on with the attach.
@ -84,7 +84,7 @@ func (e *Environment) Start() error {
// to truncate them.
if _, err := os.Stat(c.LogPath); err == nil {
if err := os.Truncate(c.LogPath, 0); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
}
}
@ -99,14 +99,14 @@ func (e *Environment) Start() error {
// exists on the system, and rebuild the container if that is required for server booting to
// occur.
if err := e.OnBeforeStart(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()
if err := e.client.ContainerStart(ctx, e.Id, types.ContainerStartOptions{}); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// No errors, good to continue through.
@ -169,7 +169,7 @@ func (e *Environment) Stop() error {
// will be terminated forcefully depending on the value of the second argument.
func (e *Environment) WaitForStop(seconds uint, terminate bool) error {
if err := e.Stop(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(seconds)*time.Second)
@ -185,20 +185,20 @@ func (e *Environment) WaitForStop(seconds uint, terminate bool) error {
if terminate {
log.WithField("container_id", e.Id).Debug("server did not stop in time, executing process termination")
return errors.WithStack(e.Terminate(os.Kill))
return errors.WithStackIf(e.Terminate(os.Kill))
}
return errors.WithStack(ctxErr)
return errors.WithStackIf(ctxErr)
}
case err := <-errChan:
if err != nil {
if terminate {
log.WithField("container_id", e.Id).WithField("error", errors.WithStack(err)).Warn("error while waiting for container stop, attempting process termination")
log.WithField("container_id", e.Id).WithField("error", errors.WithStackIf(err)).Warn("error while waiting for container stop, attempting process termination")
return errors.WithStack(e.Terminate(os.Kill))
return errors.WithStackIf(e.Terminate(os.Kill))
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
case <-ok:
}
@ -210,7 +210,7 @@ func (e *Environment) WaitForStop(seconds uint, terminate bool) error {
func (e *Environment) Terminate(signal os.Signal) error {
c, err := e.client.ContainerInspect(context.Background(), e.Id)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if !c.State.Running {

View File

@ -1,8 +1,8 @@
package docker
import (
"emperror.dev/errors"
"fmt"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
)

View File

@ -2,10 +2,10 @@ package docker
import (
"context"
"emperror.dev/errors"
"encoding/json"
"github.com/apex/log"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
"io"
"math"
@ -26,7 +26,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
stats, err := e.client.ContainerStats(context.Background(), e.Id, true)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer stats.Body.Close()
@ -41,7 +41,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
if err := dec.Decode(&v); err != nil {
if err != io.EOF {
l.WithField("error", errors.WithStack(err)).Warn("error while processing Docker stats output for container")
l.WithField("error", errors.WithStackIf(err)).Warn("error while processing Docker stats output for container")
} else {
l.Debug("io.EOF encountered during stats decode, stopping polling...")
}
@ -76,7 +76,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
}
if b, err := json.Marshal(st); err != nil {
l.WithField("error", errors.WithStack(err)).Warn("error while marshaling stats object for environment")
l.WithField("error", errors.WithStackIf(err)).Warn("error while marshaling stats object for environment")
} else {
e.Events().Publish(environment.ResourceEvent, string(b))
}

View File

@ -4,9 +4,9 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
"strconv"
)
@ -15,7 +15,7 @@ type dockerLogLine struct {
Log string `json:"log"`
}
var ErrNotAttached = errors.New("not attached to instance")
var ErrNotAttached = errors.Sentinel("not attached to instance")
func (e *Environment) setStream(s *types.HijackedResponse) {
e.mu.Lock()
@ -42,7 +42,7 @@ func (e *Environment) SendCommand(c string) error {
_, err := e.stream.Conn.Write([]byte(c + "\n"))
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Reads the log file for the server. This does not care if the server is running or not, it will
@ -54,7 +54,7 @@ func (e *Environment) Readlog(lines int) ([]string, error) {
Tail: strconv.Itoa(lines),
})
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer r.Close()

View File

@ -1,9 +1,9 @@
package events
import (
"emperror.dev/errors"
"encoding/json"
"github.com/gammazero/workerpool"
"github.com/pkg/errors"
"strings"
"sync"
)
@ -69,7 +69,7 @@ func (e *EventBus) Publish(topic string, data string) {
func (e *EventBus) PublishJson(topic string, data interface{}) error {
b, err := json.Marshal(data)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
e.Publish(topic, string(b))

2
go.mod
View File

@ -3,6 +3,7 @@ module github.com/pterodactyl/wings
go 1.13
require (
emperror.dev/errors v0.8.0
github.com/AlecAivazis/survey/v2 v2.1.0
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Jeffail/gabs/v2 v2.5.1
@ -57,7 +58,6 @@ require (
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
github.com/pkg/errors v0.9.1
github.com/pkg/profile v1.5.0
github.com/pkg/sftp v1.11.0
github.com/prometheus/common v0.11.1 // indirect

6
go.sum
View File

@ -1,5 +1,7 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
emperror.dev/errors v0.8.0 h1:4lycVEx0sdJkwDUfQ9pdu6SR0x7rgympt5f4+ok8jDk=
emperror.dev/errors v0.8.0/go.mod h1:YcRvLPh626Ubn2xqtoprejnA5nFha+TJ+2vew48kWuE=
github.com/AlecAivazis/survey/v2 v2.1.0 h1:AT4+23hOFopXYZaNGugbk7MWItkz0SfTmH/Hk92KeeE=
github.com/AlecAivazis/survey/v2 v2.1.0/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
@ -561,9 +563,13 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=

View File

@ -1,10 +1,10 @@
package installer
import (
"emperror.dev/errors"
"encoding/json"
"github.com/asaskevich/govalidator"
"github.com/buger/jsonparser"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/server"
@ -43,21 +43,21 @@ func New(data []byte) (*Installer, error) {
// Unmarshal the environment variables from the request into the server struct.
if b, _, _, err := jsonparser.Get(data, "environment"); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
} else {
cfg.EnvVars = make(environment.Variables)
if err := json.Unmarshal(b, &cfg.EnvVars); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
}
// Unmarshal the allocation mappings from the request into the server struct.
if b, _, _, err := jsonparser.Get(data, "allocations", "mappings"); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
} else {
cfg.Allocations.Mappings = make(map[string][]int)
if err := json.Unmarshal(b, &cfg.Allocations.Mappings); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
}
@ -66,7 +66,7 @@ func New(data []byte) (*Installer, error) {
c, err := api.New().GetServerConfiguration(cfg.Uuid)
if err != nil {
if !api.IsRequestError(err) {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return nil, errors.New(err.Error())

View File

@ -6,7 +6,7 @@ import (
"github.com/apex/log/handlers/cli"
color2 "github.com/fatih/color"
"github.com/mattn/go-colorable"
"github.com/pkg/errors"
"emperror.dev/errors"
"io"
"os"
"sync"
@ -88,10 +88,10 @@ func getErrorStack(err error, i bool) errors.StackTrace {
if i {
// Just abort out of this and return a stacktrace leading up to this point. It isn't perfect
// but it'll at least include what function lead to this being called which we can then handle.
return errors.Wrap(err, "failed to generate stacktrace for caught error").(tracer).StackTrace()
return errors.WrapIf(err, "failed to generate stacktrace for caught error").(tracer).StackTrace()
}
return getErrorStack(errors.Wrap(err, err.Error()), true)
return getErrorStack(errors.WrapIf(err, err.Error()), true)
}
st := e.StackTrace()
@ -101,7 +101,7 @@ func getErrorStack(err error, i bool) errors.StackTrace {
// trace since they'll point to the error that was generated by this function.
f := 0
if i {
f = 4
f = 5
}
if i && l > 9 {

View File

@ -2,11 +2,11 @@ package parser
import (
"bytes"
"emperror.dev/errors"
"github.com/Jeffail/gabs/v2"
"github.com/apex/log"
"github.com/buger/jsonparser"
"github.com/iancoleman/strcase"
"github.com/pkg/errors"
"io/ioutil"
"os"
"regexp"
@ -76,13 +76,13 @@ func (cfr *ConfigurationFileReplacement) getKeyValue(value []byte) interface{} {
func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error) {
parsed, err := gabs.ParseJSON(data)
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
for _, v := range f.Replace {
value, err := f.LookupConfigurationValue(v)
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
// Check for a wildcard character, and if found split the key on that value to
@ -101,7 +101,7 @@ func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error
continue
}
return nil, errors.Wrap(err, "failed to set config value of array child")
return nil, errors.WrapIf(err, "failed to set config value of array child")
}
}
} else {
@ -110,7 +110,7 @@ func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error
continue
}
return nil, errors.Wrap(err, "unable to set config value at pathway: "+v.Match)
return nil, errors.WrapIf(err, "unable to set config value at pathway: "+v.Match)
}
}
}
@ -138,7 +138,7 @@ func setValueAtPath(c *gabs.Container, path string, value interface{}) error {
_, err = c.SetP(value, path)
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
i, _ := strconv.Atoi(matches[2])
@ -147,7 +147,7 @@ func setValueAtPath(c *gabs.Container, path string, value interface{}) error {
ct, err := c.ArrayElementP(i, matches[1])
if err != nil {
if i != 0 || (!errors.Is(err, gabs.ErrNotArray) && !errors.Is(err, gabs.ErrNotFound)) {
return errors.Wrap(err, "error while parsing array element at path")
return errors.WrapIf(err, "error while parsing array element at path")
}
var t = make([]interface{}, 1)
@ -162,7 +162,7 @@ func setValueAtPath(c *gabs.Container, path string, value interface{}) error {
// an empty object if we have additional things to set on the array, or just an empty array type
// if there is not an object structure detected (no matches[3] available).
if _, err = c.SetP(t, matches[1]); err != nil {
return errors.Wrap(err, "failed to create empty array for missing element")
return errors.WrapIf(err, "failed to create empty array for missing element")
}
// Set our cursor to be the array element we expect, which in this case is just the first element
@ -170,7 +170,7 @@ func setValueAtPath(c *gabs.Container, path string, value interface{}) error {
// to match additional elements. In those cases the server will just have to be rebooted or something.
ct, err = c.ArrayElementP(0, matches[1])
if err != nil {
return errors.Wrap(err, "failed to find array element at path")
return errors.WrapIf(err, "failed to find array element at path")
}
}
@ -187,7 +187,7 @@ func setValueAtPath(c *gabs.Container, path string, value interface{}) error {
}
if err != nil {
return errors.Wrap(err, "failed to set value at config path: "+path)
return errors.WrapIf(err, "failed to set value at config path: "+path)
}
return nil
@ -253,7 +253,7 @@ func (f *ConfigurationFile) LookupConfigurationValue(cfr ConfigurationFileReplac
match, _, _, err := jsonparser.Get(f.configuration, path...)
if err != nil {
if err != jsonparser.KeyPathNotFoundError {
return string(match), errors.WithStack(err)
return string(match), errors.WithStackIf(err)
}
log.WithFields(log.Fields{"path": path, "filename": f.FileName}).Debug("attempted to load a configuration value that does not exist")

View File

@ -2,13 +2,13 @@ package parser
import (
"bufio"
"emperror.dev/errors"
"encoding/json"
"github.com/apex/log"
"github.com/beevik/etree"
"github.com/buger/jsonparser"
"github.com/icza/dyno"
"github.com/magiconair/properties"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"gopkg.in/ini.v1"
"gopkg.in/yaml.v2"
@ -166,17 +166,17 @@ func (f *ConfigurationFile) Parse(path string, internal bool) error {
b := strings.TrimSuffix(path, filepath.Base(path))
if err := os.MkdirAll(b, 0755); err != nil {
return errors.Wrap(err, "failed to create base directory for missing configuration file")
return errors.WrapIf(err, "failed to create base directory for missing configuration file")
} else {
if _, err := os.Create(path); err != nil {
return errors.Wrap(err, "failed to create missing configuration file")
return errors.WrapIf(err, "failed to create missing configuration file")
}
}
return f.Parse(path, true)
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Parses an xml file.
@ -348,12 +348,12 @@ func (f *ConfigurationFile) parseJsonFile(path string) error {
func (f *ConfigurationFile) parseYamlFile(path string) error {
b, err := readFileBytes(path)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
i := make(map[string]interface{})
if err := yaml.Unmarshal(b, &i); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Unmarshal the yaml data into a JSON interface such that we can work with
@ -361,20 +361,20 @@ func (f *ConfigurationFile) parseYamlFile(path string) error {
// makes working with unknown JSON significantly easier.
jsonBytes, err := json.Marshal(dyno.ConvertMapI2MapS(i))
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Now that the data is converted, treat it just like JSON and pass it to the
// iterator function to update values as necessary.
data, err := f.IterateOverJson(jsonBytes)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Remarshal the JSON into YAML format before saving it back to the disk.
marshaled, err := yaml.Marshal(data.Data())
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return ioutil.WriteFile(path, marshaled, 0644)
@ -386,7 +386,7 @@ func (f *ConfigurationFile) parseYamlFile(path string) error {
func (f *ConfigurationFile) parseTextFile(path string) error {
input, err := ioutil.ReadFile(path)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
lines := strings.Split(string(input), "\n")
@ -403,7 +403,7 @@ func (f *ConfigurationFile) parseTextFile(path string) error {
}
if err := ioutil.WriteFile(path, []byte(strings.Join(lines, "\n")), 0644); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -415,7 +415,7 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error {
// Open the file.
f2, err := os.Open(path)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
var s strings.Builder
@ -437,20 +437,20 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error {
// Handle any scanner errors.
if err := scanner.Err(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Decode the properties file.
p, err := properties.LoadFile(path, properties.UTF8)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Replace any values that need to be replaced.
for _, replace := range f.Replace {
data, err := f.LookupConfigurationValue(replace)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
v, ok := p.Get(replace.Match)
@ -462,7 +462,7 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error {
}
if _, _, err := p.Set(replace.Match, data); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
}
@ -482,7 +482,7 @@ func (f *ConfigurationFile) parsePropertiesFile(path string) error {
// Open the file for writing.
w, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer w.Close()

View File

@ -1,11 +1,11 @@
package router
import (
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
"net/http"
@ -75,7 +75,7 @@ func (e *RequestError) AbortWithStatus(status int, c *gin.Context) {
if status >= 500 {
e.logger().WithField("error", e.Err).Error("encountered HTTP/500 error while handling request")
c.Error(errors.WithStack(e))
c.Error(errors.WithStackIf(e))
} else {
e.logger().WithField("error", e.Err).Debug("encountered non-HTTP/500 error while handling request")
}
@ -99,38 +99,32 @@ func (e *RequestError) AbortWithServerError(c *gin.Context) {
// Handle specific filesystem errors for a server.
func (e *RequestError) AbortFilesystemError(c *gin.Context) {
if errors.Is(e.Err, os.ErrNotExist) {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested resource was not found.",
})
if errors.Is(e.Err, os.ErrNotExist) || filesystem.IsBadPathResolutionError(e.Err) {
if filesystem.IsBadPathResolutionError(e.Err) {
e.logger().Warn(e.Err.Error())
}
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "The requested resource was not found."})
return
}
if errors.Is(e.Err, filesystem.ErrNotEnoughDiskSpace) {
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
"error": "There is not enough disk space available to perform that action.",
})
c.AbortWithStatusJSON(http.StatusConflict, gin.H{"error": "There is not enough disk space available to perform that action."})
return
}
if strings.HasSuffix(e.Err.Error(), "file name too long") {
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"error": "File name is too long.",
})
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "File name is too long."})
return
}
if e, ok := e.Err.(*os.SyscallError); ok && e.Syscall == "readdirent" {
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
"error": "The requested directory does not exist.",
})
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"error": "The requested directory does not exist."})
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.",
})
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Cannot perform that action: file name is too long."})
return
}

View File

@ -3,9 +3,9 @@ package router
import (
"bytes"
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"net/http"
@ -227,7 +227,7 @@ func deleteServer(c *gin.Context) {
if err := os.RemoveAll(p); err != nil {
log.WithFields(log.Fields{
"path": p,
"error": errors.WithStack(err),
"error": errors.WithStackIf(err),
}).Warn("failed to remove server files during deletion process")
}
}(s.Filesystem().Path())

View File

@ -2,8 +2,8 @@ package router
import (
"context"
"emperror.dev/errors"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
@ -35,6 +35,10 @@ func getServerFileContents(c *gin.Context) {
return
}
if err := s.Filesystem().Readfile(p, c.Writer); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
} else {
c.Header("X-Mime-Type", st.Mimetype)
c.Header("Content-Length", strconv.Itoa(int(st.Info.Size())))
@ -44,10 +48,6 @@ func getServerFileContents(c *gin.Context) {
c.Header("Content-Disposition", "attachment; filename="+st.Info.Name())
c.Header("Content-Type", "application/octet-stream")
}
if err := s.Filesystem().Readfile(p, c.Writer); err != nil {
TrackedServerError(err, s).AbortFilesystemError(c)
return
}
}
@ -413,12 +413,12 @@ func postServerUploadFiles(c *gin.Context) {
func handleFileUpload(p string, s *server.Server, header *multipart.FileHeader) error {
file, err := header.Open()
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer file.Close()
if err := s.Filesystem().Writefile(p, file); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil

View File

@ -4,12 +4,12 @@ import (
"bufio"
"bytes"
"crypto/sha256"
"emperror.dev/errors"
"encoding/hex"
"github.com/apex/log"
"github.com/buger/jsonparser"
"github.com/gin-gonic/gin"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/installer"
@ -157,7 +157,7 @@ func postTransfer(c *gin.Context) {
// Make a new GET request to the URL the panel gave us.
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.WithField("error", errors.WithStack(err)).Error("failed to create http request for archive transfer")
log.WithField("error", errors.WithStackIf(err)).Error("failed to create http request for archive transfer")
return
}
@ -167,7 +167,7 @@ func postTransfer(c *gin.Context) {
// Execute the http request.
res, err := client.Do(req)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to send archive http request")
l.WithField("error", errors.WithStackIf(err)).Error("failed to send archive http request")
return
}
defer res.Body.Close()
@ -176,12 +176,12 @@ func postTransfer(c *gin.Context) {
if res.StatusCode != 200 {
_, err := ioutil.ReadAll(res.Body)
if err != nil {
l.WithField("error", errors.WithStack(err)).WithField("status", res.StatusCode).Error("failed read transfer response body")
l.WithField("error", errors.WithStackIf(err)).WithField("status", res.StatusCode).Error("failed read transfer response body")
return
}
l.WithField("error", errors.WithStack(err)).WithField("status", res.StatusCode).Error("failed to request server archive")
l.WithField("error", errors.WithStackIf(err)).WithField("status", res.StatusCode).Error("failed to request server archive")
return
}
@ -193,12 +193,12 @@ func postTransfer(c *gin.Context) {
_, err = os.Stat(archivePath)
if err != nil {
if !os.IsNotExist(err) {
l.WithField("error", errors.WithStack(err)).Error("failed to stat archive file")
l.WithField("error", errors.WithStackIf(err)).Error("failed to stat archive file")
return
}
} else {
if err := os.Remove(archivePath); err != nil {
l.WithField("error", errors.WithStack(err)).Warn("failed to remove old archive file")
l.WithField("error", errors.WithStackIf(err)).Warn("failed to remove old archive file")
return
}
@ -207,7 +207,7 @@ func postTransfer(c *gin.Context) {
// Create the file.
file, err := os.Create(archivePath)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to open archive on disk")
l.WithField("error", errors.WithStackIf(err)).Error("failed to open archive on disk")
return
}
@ -216,14 +216,14 @@ func postTransfer(c *gin.Context) {
buf := make([]byte, 1024*4)
_, err = io.CopyBuffer(file, res.Body, buf)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to copy archive file to disk")
l.WithField("error", errors.WithStackIf(err)).Error("failed to copy archive file to disk")
return
}
// Close the file so it can be opened to verify the checksum.
if err := file.Close(); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to close archive file")
l.WithField("error", errors.WithStackIf(err)).Error("failed to close archive file")
return
}
@ -233,7 +233,7 @@ func postTransfer(c *gin.Context) {
// Open the archive file for computing a checksum.
file, err = os.Open(archivePath)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to open archive on disk")
l.WithField("error", errors.WithStackIf(err)).Error("failed to open archive on disk")
return
}
@ -241,7 +241,7 @@ func postTransfer(c *gin.Context) {
hash := sha256.New()
buf = make([]byte, 1024*4)
if _, err := io.CopyBuffer(hash, file, buf); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to copy archive file for checksum verification")
l.WithField("error", errors.WithStackIf(err)).Error("failed to copy archive file for checksum verification")
return
}
@ -253,7 +253,7 @@ func postTransfer(c *gin.Context) {
// Close the file.
if err := file.Close(); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to close archive file after calculating checksum")
l.WithField("error", errors.WithStackIf(err)).Error("failed to close archive file after calculating checksum")
return
}
@ -269,7 +269,7 @@ func postTransfer(c *gin.Context) {
// Create a new server installer (note this does not execute the install script)
i, err := installer.New(serverData)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to validate received server data")
l.WithField("error", errors.WithStackIf(err)).Error("failed to validate received server data")
return
}
@ -284,7 +284,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 {
l.WithField("error", errors.WithStack(err)).Error("failed to extract server archive")
l.WithField("error", errors.WithStackIf(err)).Error("failed to extract server archive")
return
}
@ -299,7 +299,7 @@ func postTransfer(c *gin.Context) {
err = api.New().SendTransferSuccess(serverID)
if err != nil {
if !api.IsRequestError(err) {
l.WithField("error", errors.WithStack(err)).Error("failed to notify panel of transfer success")
l.WithField("error", errors.WithStackIf(err)).Error("failed to notify panel of transfer success")
return
}

View File

@ -2,13 +2,13 @@ package websocket
import (
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/gbrlsnchs/jwt/v3"
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/environment/docker"
@ -41,10 +41,10 @@ type Handler struct {
}
var (
ErrJwtNotPresent = errors.New("jwt: no jwt present")
ErrJwtNoConnectPerm = errors.New("jwt: missing connect permission")
ErrJwtUuidMismatch = errors.New("jwt: server uuid mismatch")
ErrJwtOnDenylist = errors.New("jwt: created too far in past (denylist)")
ErrJwtNotPresent = errors.Sentinel("jwt: no jwt present")
ErrJwtNoConnectPerm = errors.Sentinel("jwt: missing connect permission")
ErrJwtUuidMismatch = errors.Sentinel("jwt: server uuid mismatch")
ErrJwtOnDenylist = errors.Sentinel("jwt: created too far in past (denylist)")
)
func IsJwtError(err error) bool {
@ -108,7 +108,7 @@ func GetHandler(s *server.Server, w http.ResponseWriter, r *http.Request) (*Hand
u, err := uuid.NewRandom()
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return &Handler{

View File

@ -2,9 +2,9 @@ package server
import (
"crypto/sha256"
"emperror.dev/errors"
"encoding/hex"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/server/filesystem"
"io"
@ -41,7 +41,7 @@ func (a *Archiver) Exists() bool {
func (a *Archiver) Stat() (*filesystem.Stat, error) {
s, err := os.Stat(a.Path())
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return &filesystem.Stat{
@ -99,7 +99,7 @@ func (a *Archiver) DeleteIfExists() error {
}
if err := os.Remove(a.Path()); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil

View File

@ -2,8 +2,8 @@ package server
import (
"bufio"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/server/backup"
"os"
@ -80,7 +80,7 @@ func (s *Server) Backup(b backup.BackupInterface) error {
// Get the included files based on the root path and the ignored files provided.
inc, err := s.GetIncludedBackupFiles(b.Ignored())
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
ad, err := b.Generate(inc, s.Filesystem().Path())
@ -100,7 +100,7 @@ func (s *Server) Backup(b backup.BackupInterface) error {
"file_size": 0,
})
return errors.Wrap(err, "error while generating server backup")
return errors.WrapIf(err, "error while generating server backup")
}
// Try to notify the panel about the status of this backup. If for some reason this request

View File

@ -3,9 +3,9 @@ package backup
import (
"archive/tar"
"context"
"emperror.dev/errors"
"github.com/apex/log"
gzip "github.com/klauspost/pgzip"
"github.com/pkg/errors"
"github.com/remeh/sizedwaitgroup"
"golang.org/x/sync/errgroup"
"io"
@ -26,7 +26,7 @@ type Archive struct {
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 errors.WithStack(err)
return errors.WithStackIf(err)
}
defer f.Close()
@ -58,7 +58,7 @@ func (a *Archive) Create(dst string, ctx context.Context) error {
select {
case <-ctx.Done():
return errors.WithStack(ctx.Err())
return errors.WithStackIf(ctx.Err())
default:
return a.addToArchive(p, tw)
}
@ -75,7 +75,7 @@ func (a *Archive) Create(dst string, ctx context.Context) error {
log.WithField("location", dst).Warn("failed to delete corrupted backup archive")
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -91,7 +91,7 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
return nil
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer f.Close()
@ -102,7 +102,7 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
return nil
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
header := &tar.Header{
@ -120,12 +120,12 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
defer a.Unlock()
if err := w.WriteHeader(header); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
buf := make([]byte, 4*1024)
if _, err := io.CopyBuffer(w, f, buf); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil

View File

@ -2,9 +2,9 @@ package backup
import (
"crypto/sha1"
"emperror.dev/errors"
"encoding/hex"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"io"
@ -87,7 +87,7 @@ func (b *Backup) Path() string {
func (b *Backup) Size() (int64, error) {
st, err := os.Stat(b.Path())
if err != nil {
return 0, errors.WithStack(err)
return 0, errors.WithStackIf(err)
}
return st.Size(), nil
@ -99,7 +99,7 @@ func (b *Backup) Checksum() ([]byte, error) {
f, err := os.Open(b.Path())
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer f.Close()

View File

@ -2,7 +2,7 @@ package backup
import (
"context"
"github.com/pkg/errors"
"emperror.dev/errors"
"os"
)
@ -24,7 +24,7 @@ func LocateLocal(uuid string) (*LocalBackup, os.FileInfo, error) {
st, err := os.Stat(b.Path())
if err != nil {
return nil, nil, errors.WithStack(err)
return nil, nil, errors.WithStackIf(err)
}
if st.IsDir() {
@ -48,7 +48,7 @@ func (b *LocalBackup) Generate(included *IncludedFiles, prefix string) (*Archive
}
if err := a.Create(b.Path(), context.Background()); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return b.Details(), nil

View File

@ -1,8 +1,8 @@
package backup
import (
"emperror.dev/errors"
"fmt"
"github.com/pkg/errors"
)
type Request struct {

View File

@ -3,9 +3,9 @@ package backup
import (
"bytes"
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"io"
"net/http"
@ -31,17 +31,17 @@ func (s *S3Backup) Generate(included *IncludedFiles, prefix string) (*ArchiveDet
}
if err := a.Create(s.Path(), context.Background()); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
rc, err := os.Open(s.Path())
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer rc.Close()
if err := s.generateRemoteRequest(rc); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return s.Details(), err

View File

@ -2,9 +2,9 @@ package server
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/mitchellh/colorstring"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"sync"
@ -12,7 +12,7 @@ import (
"time"
)
var ErrTooMuchConsoleData = errors.New("console is outputting too much data")
var ErrTooMuchConsoleData = errors.Sentinel("console is outputting too much data")
type ConsoleThrottler struct {
mu sync.Mutex

View File

@ -1,8 +1,8 @@
package server
import (
"emperror.dev/errors"
"fmt"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"sync"
@ -57,7 +57,7 @@ func (s *Server) handleServerCrash() error {
exitCode, oomKilled, err := s.Environment.ExitState()
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// If the system is not configured to detect a clean exit code as a crash, and the

View File

@ -1,9 +1,9 @@
package server
import "github.com/pkg/errors"
import "emperror.dev/errors"
var ErrIsRunning = errors.New("server is running")
var ErrSuspended = errors.New("server is currently in a suspended state")
var ErrIsRunning = errors.Sentinel("server is running")
var ErrSuspended = errors.Sentinel("server is currently in a suspended state")
type crashTooFrequent struct {
}

View File

@ -1,7 +1,7 @@
package server
import (
"github.com/pkg/errors"
"emperror.dev/errors"
"github.com/pterodactyl/wings/server/filesystem"
"os"
)
@ -13,12 +13,12 @@ func (s *Server) Filesystem() *filesystem.Filesystem {
// Ensures that the data directory for the server instance exists.
func (s *Server) EnsureDataDirectoryExists() error {
if _, err := os.Stat(s.fs.Path()); err != nil && !os.IsNotExist(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
} else if err != nil {
// Create the server data directory because it does not currently exist
// on the system.
if err := os.MkdirAll(s.fs.Path(), 0700); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err := s.fs.Chown("/"); err != nil {

View File

@ -2,9 +2,9 @@ package filesystem
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/karrick/godirwalk"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/server/backup"
ignore "github.com/sabhiram/go-gitignore"
"os"
@ -41,7 +41,7 @@ func (fs *Filesystem) GetIncludedFiles(dir string, ignored []string) (*backup.In
if e.IsSymlink() {
sp, err = fs.SafePath(p)
if err != nil {
if errors.Is(err, ErrBadPathResolution) {
if IsBadPathResolutionError(err) {
return godirwalk.SkipThis
}
@ -65,7 +65,7 @@ func (fs *Filesystem) GetIncludedFiles(dir string, ignored []string) (*backup.In
},
})
return inc, errors.WithStack(err)
return inc, errors.WithStackIf(err)
}
// Compresses all of the files matching the given paths in the specified directory. This function
@ -115,7 +115,7 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er
// use the resolved location for the rest of this function.
sp, err = fs.SafePath(p)
if err != nil {
if errors.Is(err, ErrBadPathResolution) {
if IsBadPathResolutionError(err) {
return godirwalk.SkipThis
}
@ -141,7 +141,7 @@ func (fs *Filesystem) CompressFiles(dir string, paths []string) (os.FileInfo, er
d := path.Join(cleanedRootDir, fmt.Sprintf("archive-%s.tar.gz", strings.ReplaceAll(time.Now().Format(time.RFC3339), ":", "")))
if err := a.Create(d, context.Background()); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
f, err := os.Stat(d)

View File

@ -4,9 +4,9 @@ import (
"archive/tar"
"archive/zip"
"compress/gzip"
"emperror.dev/errors"
"fmt"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"os"
"path/filepath"
"reflect"
@ -47,10 +47,10 @@ func (fs *Filesystem) SpaceAvailableForDecompression(dir string, file string) (b
return false, ErrUnknownArchiveFormat
}
return false, errors.WithStack(err)
return false, errors.WithStackIf(err)
}
return true, errors.WithStack(err)
return true, errors.WithStackIf(err)
}
// Decompress a file in a given directory by using the archiver tool to infer the file
@ -60,12 +60,12 @@ func (fs *Filesystem) SpaceAvailableForDecompression(dir string, file string) (b
func (fs *Filesystem) DecompressFile(dir string, file string) error {
source, err := fs.SafePath(filepath.Join(dir, file))
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Make sure the file exists basically.
if _, err := os.Stat(source); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Walk over all of the files spinning up an additional go-routine for each file we've encountered
@ -93,17 +93,17 @@ func (fs *Filesystem) DecompressFile(dir string, file string) error {
p, err := fs.SafePath(filepath.Join(dir, name))
if err != nil {
return errors.Wrap(err, "failed to generate a safe path to server file")
return errors.WrapIf(err, "failed to generate a safe path to server file")
}
return errors.Wrap(fs.Writefile(p, f), "could not extract file from archive")
return errors.WrapIf(fs.Writefile(p, f), "could not extract file from archive")
})
if err != nil {
if strings.HasPrefix(err.Error(), "format ") {
return errors.WithStack(ErrUnknownArchiveFormat)
return errors.WithStackIf(ErrUnknownArchiveFormat)
}
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil

View File

@ -1,9 +1,9 @@
package filesystem
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/karrick/godirwalk"
"github.com/pkg/errors"
"sync"
"sync/atomic"
"syscall"
@ -153,7 +153,7 @@ func (fs *Filesystem) updateCachedDiskUsage() (int64, error) {
func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
d, err := fs.SafePath(dir)
if err != nil {
return 0, errors.WithStack(err)
return 0, errors.WithStackIf(err)
}
var size int64
@ -167,7 +167,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
// it. Otherwise, allow it to continue.
if e.IsSymlink() {
if _, err := fs.SafePath(p); err != nil {
if errors.Is(err, ErrBadPathResolution) {
if IsBadPathResolutionError(err) {
return godirwalk.SkipThis
}
@ -184,7 +184,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
},
})
return size, errors.WithStack(err)
return size, errors.WithStackIf(err)
}
// Helper function to determine if a server has space available for a file of a given size.

View File

@ -1,16 +1,43 @@
package filesystem
import (
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"os"
"path/filepath"
)
var ErrIsDirectory = errors.New("filesystem: is a directory")
var ErrNotEnoughDiskSpace = errors.New("filesystem: not enough disk space")
var ErrBadPathResolution = errors.New("filesystem: invalid path resolution")
var ErrUnknownArchiveFormat = errors.New("filesystem: unknown archive format")
var ErrIsDirectory = errors.Sentinel("filesystem: is a directory")
var ErrNotEnoughDiskSpace = errors.Sentinel("filesystem: not enough disk space")
var ErrUnknownArchiveFormat = errors.Sentinel("filesystem: unknown archive format")
type BadPathResolutionError struct {
path string
resolved string
}
// Returns the specific error for a bad path resolution.
func (b *BadPathResolutionError) Error() string {
r := b.resolved
if r == "" {
r = "<empty>"
}
return fmt.Sprintf("filesystem: server path [%s] resolves to a location outside the server root: %s", b.path, r)
}
// Returns a new BadPathResolution error.
func NewBadPathResolution(path string, resolved string) *BadPathResolutionError {
return &BadPathResolutionError{path, resolved}
}
// Determines if the given error is a bad path resolution error.
func IsBadPathResolutionError(err error) bool {
if _, ok := err.(*BadPathResolutionError); ok {
return true
}
return false
}
// Generates an error logger instance with some basic information.
func (fs *Filesystem) error(err error) *log.Entry {
@ -23,8 +50,8 @@ func (fs *Filesystem) error(err error) *log.Entry {
// directory, otherwise return nil. Returning this error for a file will stop the walking
// for the remainder of the directory. This is assuming an os.FileInfo struct was even returned.
func (fs *Filesystem) handleWalkerError(err error, f os.FileInfo) error {
if !errors.Is(err, ErrBadPathResolution) {
return err
if !IsBadPathResolutionError(err) {
return errors.WithStackIf(err)
}
if f != nil && f.IsDir() {

View File

@ -2,9 +2,9 @@ package filesystem
import (
"bufio"
"emperror.dev/errors"
"github.com/gabriel-vasile/mimetype"
"github.com/karrick/godirwalk"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"io"
@ -80,7 +80,7 @@ func (fs *Filesystem) Readfile(p string, w io.Writer) error {
func (fs *Filesystem) Writefile(p string, r io.Reader) error {
cleaned, err := fs.SafePath(p)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
var currentSize int64
@ -88,15 +88,15 @@ func (fs *Filesystem) Writefile(p string, r io.Reader) error {
// to it and an empty file. We'll then write to it later on after this completes.
if stat, err := os.Stat(cleaned); err != nil {
if !os.IsNotExist(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err := os.MkdirAll(filepath.Dir(cleaned), 0755); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err := fs.Chown(filepath.Dir(cleaned)); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else {
if stat.IsDir() {
@ -119,7 +119,7 @@ func (fs *Filesystem) Writefile(p string, r io.Reader) error {
// truncate the existing file.
file, err := o.open(cleaned, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer file.Close()
@ -138,7 +138,7 @@ func (fs *Filesystem) Writefile(p string, r io.Reader) error {
func (fs *Filesystem) CreateDirectory(name string, p string) error {
cleaned, err := fs.SafePath(path.Join(p, name))
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return os.MkdirAll(cleaned, 0755)
@ -148,12 +148,12 @@ func (fs *Filesystem) CreateDirectory(name string, p string) error {
func (fs *Filesystem) Rename(from string, to string) error {
cleanedFrom, err := fs.SafePath(from)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
cleanedTo, err := fs.SafePath(to)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// If the target file or directory already exists the rename function will fail, so just
@ -171,7 +171,7 @@ func (fs *Filesystem) Rename(from string, to string) error {
// we're not at the root directory level.
if d != fs.Path() {
if mkerr := os.MkdirAll(d, 0755); mkerr != nil {
return errors.Wrap(mkerr, "failed to create directory structure for file rename")
return errors.WrapIf(mkerr, "failed to create directory structure for file rename")
}
}
@ -185,7 +185,7 @@ func (fs *Filesystem) Rename(from string, to string) error {
func (fs *Filesystem) Chown(path string) error {
cleaned, err := fs.SafePath(path)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if fs.isTest {
@ -197,7 +197,7 @@ func (fs *Filesystem) Chown(path string) error {
// Start by just chowning the initial path that we received.
if err := os.Chown(cleaned, uid, gid); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// If this is not a directory we can now return from the function, there is nothing
@ -268,12 +268,12 @@ func (fs *Filesystem) findCopySuffix(dir string, name string, extension string)
func (fs *Filesystem) Copy(p string) error {
cleaned, err := fs.SafePath(p)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
s, err := os.Stat(cleaned)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
} else if s.IsDir() || !s.Mode().IsRegular() {
// If this is a directory or not a regular file, just throw a not-exist error
// since anything calling this function should understand what that means.
@ -300,7 +300,7 @@ func (fs *Filesystem) Copy(p string) error {
source, err := os.Open(cleaned)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer source.Close()
@ -324,7 +324,7 @@ func (fs *Filesystem) Delete(p string) error {
// exists within the data directory.
resolved := fs.unsafeFilePath(p)
if !fs.unsafeIsInDataDirectory(resolved) {
return ErrBadPathResolution
return NewBadPathResolution(p, resolved)
}
// Block any whoopsies.

View File

@ -134,22 +134,22 @@ func TestFilesystem_SafePath(t *testing.T) {
g.It("blocks access to files outside the root directory", func() {
p, err := fs.SafePath("../test.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
g.Assert(p).Equal("")
p, err = fs.SafePath("/../test.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
g.Assert(p).Equal("")
p, err = fs.SafePath("./foo/../../test.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
g.Assert(p).Equal("")
p, err = fs.SafePath("..")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
g.Assert(p).Equal("")
})
})
@ -185,7 +185,7 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
err := fs.Readfile("symlinked.txt", &b)
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -195,7 +195,7 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
err := fs.Writefile("symlinked.txt", r)
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot write a file to a directory symlinked outside the root", func() {
@ -203,7 +203,7 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
err := fs.Writefile("external_dir/foo.txt", r)
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -211,19 +211,19 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
g.It("cannot create a directory outside the root", func() {
err := fs.CreateDirectory("my_dir", "external_dir")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot create a nested directory outside the root", func() {
err := fs.CreateDirectory("my/nested/dir", "external_dir/foo/bar")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot create a nested directory outside the root", func() {
err := fs.CreateDirectory("my/nested/dir", "external_dir/server")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -231,13 +231,13 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
g.It("cannot rename a file symlinked outside the directory root", func() {
err := fs.Rename("symlinked.txt", "foo.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot rename a symlinked directory outside the root", func() {
err := fs.Rename("external_dir", "foo")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot rename a file to a location outside the directory root", func() {
@ -245,7 +245,7 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
err := fs.Rename("my_file.txt", "external_dir/my_file.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -253,13 +253,13 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
g.It("cannot chown a file symlinked outside the directory root", func() {
err := fs.Chown("symlinked.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot chown a directory symlinked outside the directory root", func() {
err := fs.Chown("external_dir")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -267,7 +267,7 @@ func TestFilesystem_Blocks_Symlinks(t *testing.T) {
g.It("cannot copy a file symlinked outside the directory root", func() {
err := fs.Copy("symlinked.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
})
@ -325,7 +325,7 @@ func TestFilesystem_Readfile(t *testing.T) {
err = fs.Readfile("/../test.txt", buf)
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.AfterEach(func() {
@ -386,7 +386,7 @@ func TestFilesystem_Writefile(t *testing.T) {
err := fs.Writefile("/some/../foo/../../test.txt", r)
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("cannot write a file that exceeds the disk limits", func() {
@ -477,7 +477,7 @@ func TestFilesystem_CreateDirectory(t *testing.T) {
g.It("should not allow the creation of directories outside the root", func() {
err := fs.CreateDirectory("test", "e/../../something")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("should not increment the disk usage", func() {
@ -527,7 +527,7 @@ func TestFilesystem_Rename(t *testing.T) {
g.It("does not allow renaming to a location outside the root", func() {
err := fs.Rename("source.txt", "../target.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("does not allow renaming from a location outside the root", func() {
@ -535,7 +535,7 @@ func TestFilesystem_Rename(t *testing.T) {
err = fs.Rename("/../ext-source.txt", "target.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("allows a file to be renamed", func() {
@ -613,7 +613,7 @@ func TestFilesystem_Copy(t *testing.T) {
err = fs.Copy("../ext-source.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("should return an error if the source directory is outside the root", func() {
@ -625,11 +625,11 @@ func TestFilesystem_Copy(t *testing.T) {
err = fs.Copy("../nested/in/dir/ext-source.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
err = fs.Copy("nested/in/../../../nested/in/dir/ext-source.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("should return an error if the source is a directory", func() {
@ -721,7 +721,7 @@ func TestFilesystem_Delete(t *testing.T) {
err = fs.Delete("../ext-source.txt")
g.Assert(err).IsNotNil()
g.Assert(errors.Is(err, ErrBadPathResolution)).IsTrue()
g.Assert(IsBadPathResolutionError(err)).IsTrue()
})
g.It("does not allow the deletion of the root directory", func() {

View File

@ -2,6 +2,7 @@ package filesystem
import (
"context"
"emperror.dev/errors"
"golang.org/x/sync/errgroup"
"os"
"path/filepath"
@ -23,9 +24,9 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
// At the same time, evaluate the symlink status and determine where this file or folder
// is truly pointing to.
p, err := filepath.EvalSymlinks(r)
ep, err := filepath.EvalSymlinks(r)
if err != nil && !os.IsNotExist(err) {
return "", err
return "", errors.WithStackIf(err)
} else if os.IsNotExist(err) {
// The requested directory doesn't exist, so at this point we need to iterate up the
// path chain until we hit a directory that _does_ exist and can be validated.
@ -53,7 +54,7 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
// attempt going on, and we should NOT resolve this path for them.
if nonExistentPathResolution != "" {
if !fs.unsafeIsInDataDirectory(nonExistentPathResolution) {
return "", ErrBadPathResolution
return "", NewBadPathResolution(p, nonExistentPathResolution)
}
// If the nonExistentPathResolution variable is not empty then the initial path requested
@ -66,11 +67,11 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
// If the requested directory from EvalSymlinks begins with the server root directory go
// ahead and return it. If not we'll return an error which will block any further action
// on the file.
if fs.unsafeIsInDataDirectory(p) {
return p, nil
if fs.unsafeIsInDataDirectory(ep) {
return ep, nil
}
return "", ErrBadPathResolution
return "", NewBadPathResolution(p, r)
}
// Generate a path to the file by cleaning it up and appending the root server path to it. This

View File

@ -1,6 +1,7 @@
package filesystem
import (
"emperror.dev/errors"
"encoding/json"
"github.com/gabriel-vasile/mimetype"
"os"
@ -50,14 +51,14 @@ func (fs *Filesystem) Stat(p string) (*Stat, error) {
func (fs *Filesystem) unsafeStat(p string) (*Stat, error) {
s, err := os.Stat(p)
if err != nil {
return nil, err
return nil, errors.WithStackIf(err)
}
var m *mimetype.MIME
if !s.IsDir() {
m, err = mimetype.DetectFile(p)
if err != nil {
return nil, err
return nil, errors.WithStackIf(err)
}
}

View File

@ -4,12 +4,12 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -90,7 +90,7 @@ func (s *Server) internalInstall() error {
script, err := api.New().GetInstallationScript(s.Id())
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.New(err.Error())
@ -98,7 +98,7 @@ func (s *Server) internalInstall() error {
p, err := NewInstallationProcess(s, &script)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
s.Log().Info("beginning installation process for server")
@ -130,7 +130,7 @@ func NewInstallationProcess(s *Server, script *api.InstallationScript) (*Install
s.installer.cancel = &cancel
if c, err := environment.DockerClient(); err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
} else {
proc.client = c
proc.context = ctx
@ -193,7 +193,7 @@ func (ip *InstallationProcess) RemoveContainer() {
})
if err != nil && !client.IsErrNotFound(err) {
ip.Server.Log().WithField("error", errors.WithStack(err)).Warn("failed to delete server install container")
ip.Server.Log().WithField("error", errors.WithStackIf(err)).Warn("failed to delete server install container")
}
}
@ -218,14 +218,14 @@ func (ip *InstallationProcess) Run() error {
}()
if err := ip.BeforeExecute(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
cid, err := ip.Execute()
if err != nil {
ip.RemoveContainer()
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// If this step fails, log a warning but don't exit out of the process. This is completely
@ -248,12 +248,12 @@ func (ip *InstallationProcess) writeScriptToDisk() error {
// Make sure the temp directory root exists before trying to make a directory within it. The
// ioutil.TempDir call expects this base to exist, it won't create it for you.
if err := os.MkdirAll(ip.tempDir(), 0700); err != nil {
return errors.Wrap(err, "could not create temporary directory for install process")
return errors.WrapIf(err, "could not create temporary directory for install process")
}
f, err := os.OpenFile(filepath.Join(ip.tempDir(), "install.sh"), os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return errors.Wrap(err, "failed to write server installation script to disk before mount")
return errors.WrapIf(err, "failed to write server installation script to disk before mount")
}
defer f.Close()
@ -265,7 +265,7 @@ func (ip *InstallationProcess) writeScriptToDisk() error {
}
if err := scanner.Err(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
w.Flush()
@ -277,7 +277,7 @@ func (ip *InstallationProcess) writeScriptToDisk() error {
func (ip *InstallationProcess) pullInstallationImage() error {
r, err := ip.client.ImagePull(ip.context, ip.Script.ContainerImage, types.ImagePullOptions{})
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Block continuation until the image has been pulled successfully.
@ -287,7 +287,7 @@ func (ip *InstallationProcess) pullInstallationImage() error {
}
if err := scanner.Err(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -298,11 +298,11 @@ func (ip *InstallationProcess) pullInstallationImage() error {
// manner, if either one fails the error is returned.
func (ip *InstallationProcess) BeforeExecute() error {
if err := ip.writeScriptToDisk(); err != nil {
return errors.Wrap(err, "failed to write installation script to disk")
return errors.WrapIf(err, "failed to write installation script to disk")
}
if err := ip.pullInstallationImage(); err != nil {
return errors.Wrap(err, "failed to pull updated installation container image for server")
return errors.WrapIf(err, "failed to pull updated installation container image for server")
}
opts := types.ContainerRemoveOptions{
@ -312,7 +312,7 @@ func (ip *InstallationProcess) BeforeExecute() error {
if err := ip.client.ContainerRemove(ip.context, ip.Server.Id()+"_installer", opts); err != nil {
if !client.IsErrNotFound(err) {
return errors.Wrap(err, "failed to remove existing install container for server")
return errors.WrapIf(err, "failed to remove existing install container for server")
}
}
@ -338,12 +338,12 @@ func (ip *InstallationProcess) AfterExecute(containerId string) error {
})
if err != nil && !client.IsErrNotFound(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
f, err := os.OpenFile(ip.GetLogPath(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer f.Close()
@ -372,15 +372,15 @@ func (ip *InstallationProcess) AfterExecute(containerId string) error {
| ------------------------------
`)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err := tmpl.Execute(f, ip); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if _, err := io.Copy(f, reader); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil
@ -448,7 +448,7 @@ func (ip *InstallationProcess) Execute() (string, error) {
r, err := ip.client.ContainerCreate(ip.context, conf, hostConf, nil, ip.Server.Id()+"_installer")
if err != nil {
return "", errors.WithStack(err)
return "", errors.WithStackIf(err)
}
ip.Server.Log().WithField("container_id", r.ID).Info("running installation script for server in container")
@ -468,7 +468,7 @@ func (ip *InstallationProcess) Execute() (string, error) {
select {
case err := <-eChan:
if err != nil {
return "", errors.WithStack(err)
return "", errors.WithStackIf(err)
}
case <-sChan:
}
@ -487,7 +487,7 @@ func (ip *InstallationProcess) StreamOutput(id string) error {
})
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
defer reader.Close()
@ -500,7 +500,7 @@ func (ip *InstallationProcess) StreamOutput(id string) error {
if err := s.Err(); err != nil {
ip.Server.Log().WithFields(log.Fields{
"container_id": id,
"error": errors.WithStack(err),
"error": errors.WithStackIf(err),
}).Warn("error processing scanner line in installation output for server")
}
@ -515,7 +515,7 @@ func (s *Server) SyncInstallState(successful bool) error {
err := api.New().SendInstallationStatus(s.Id(), successful)
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.New(err.Error())

View File

@ -1,9 +1,9 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -77,7 +77,7 @@ func (s *Server) StartEventListeners() {
s.Environment.SetState(environment.ProcessRunningState)
}
s.Log().WithField("error", errors.WithStack(err)).Error("failed to terminate environment after triggering throttle")
s.Log().WithField("error", errors.WithStackIf(err)).Error("failed to terminate environment after triggering throttle")
}
}()
}
@ -106,7 +106,7 @@ func (s *Server) StartEventListeners() {
stats := func(e events.Event) {
st := new(environment.Stats)
if err := json.Unmarshal([]byte(e.Data), st); err != nil {
s.Log().WithField("error", errors.WithStack(err)).Warn("failed to unmarshal server environment stats")
s.Log().WithField("error", errors.WithStackIf(err)).Warn("failed to unmarshal server environment stats")
return
}

View File

@ -1,12 +1,12 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/creasty/defaults"
"github.com/gammazero/workerpool"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -35,7 +35,7 @@ func LoadDirectory() error {
configs, err := api.New().GetServers()
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return errors.New(err.Error())
@ -89,12 +89,12 @@ func LoadDirectory() error {
func FromConfiguration(data api.ServerConfigurationResponse) (*Server, error) {
cfg := Configuration{}
if err := defaults.Set(&cfg); err != nil {
return nil, errors.Wrap(err, "failed to set struct defaults for server configuration")
return nil, errors.WrapIf(err, "failed to set struct defaults for server configuration")
}
s := new(Server)
if err := defaults.Set(s); err != nil {
return nil, errors.Wrap(err, "failed to set struct defaults for server")
return nil, errors.WrapIf(err, "failed to set struct defaults for server")
}
s.cfg = cfg

View File

@ -2,7 +2,7 @@ package server
import (
"context"
"github.com/pkg/errors"
"emperror.dev/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/server/filesystem"
@ -80,13 +80,13 @@ func (s *Server) HandlePowerAction(action PowerAction, waitSeconds ...int) error
// time than that passes an error will be propagated back up the chain and this
// request will be aborted.
if err := s.powerLock.Acquire(ctx, 1); err != nil {
return errors.Wrap(err, "could not acquire lock on power state")
return errors.WrapIf(err, "could not acquire lock on power state")
}
} else {
// If no wait duration was provided we will attempt to immediately acquire the lock
// and bail out with a context deadline error if it is not acquired immediately.
if ok := s.powerLock.TryAcquire(1); !ok {
return errors.Wrap(context.DeadlineExceeded, "could not acquire lock on power state")
return errors.WrapIf(context.DeadlineExceeded, "could not acquire lock on power state")
}
}
@ -149,7 +149,7 @@ func (s *Server) HandlePowerAction(action PowerAction, waitSeconds ...int) error
func (s *Server) onBeforeStart() error {
s.Log().Info("syncing server configuration with panel")
if err := s.Sync(); err != nil {
return errors.Wrap(err, "unable to sync server data from Panel instance")
return errors.WrapIf(err, "unable to sync server data from Panel instance")
}
// Disallow start & restart if the server is suspended. Do this check after performing a sync
@ -185,7 +185,7 @@ func (s *Server) onBeforeStart() error {
s.PublishConsoleOutputFromDaemon("Ensuring file permissions are set correctly, this could take a few seconds...")
// Ensure all of the server file permissions are set correctly before booting the process.
if err := s.Filesystem().Chown("/"); err != nil {
return errors.Wrap(err, "failed to chown root server directory during pre-boot process")
return errors.WrapIf(err, "failed to chown root server directory during pre-boot process")
}
}

View File

@ -2,9 +2,9 @@ package server
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -115,7 +115,7 @@ func (s *Server) Sync() error {
cfg, err := api.New().GetServerConfiguration(s.Id())
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
if err.(*api.RequestError).Status == "404" {
@ -131,7 +131,7 @@ func (s *Server) Sync() error {
func (s *Server) SyncWithConfiguration(cfg api.ServerConfigurationResponse) error {
// Update the data structure and persist it to the disk.
if err := s.UpdateDataStructure(cfg.Settings); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
s.Lock()
@ -171,7 +171,7 @@ func (s *Server) IsBootable() bool {
func (s *Server) CreateEnvironment() error {
// Ensure the data directory exists before getting too far through this process.
if err := s.EnsureDataDirectoryExists(); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return s.Environment.Create()

View File

@ -1,8 +1,8 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"io"
@ -22,14 +22,14 @@ func CachedServerStates() (map[string]string, error) {
// Open the states file.
f, err := os.OpenFile(config.Get().System.GetStatesPath(), os.O_RDONLY|os.O_CREATE, 0644)
if err != nil {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
defer f.Close()
// Convert the json object to a map.
states := map[string]string{}
if err := json.NewDecoder(f).Decode(&states); err != nil && err != io.EOF {
return nil, errors.WithStack(err)
return nil, errors.WithStackIf(err)
}
return states, nil
@ -46,7 +46,7 @@ func saveServerStates() error {
// Convert the map to a json object.
data, err := json.Marshal(states)
if err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
stateMutex.Lock()
@ -54,7 +54,7 @@ func saveServerStates() error {
// Write the data to the file
if err := ioutil.WriteFile(config.Get().System.GetStatesPath(), data, 0644); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
return nil

View File

@ -1,10 +1,10 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/buger/jsonparser"
"github.com/imdario/mergo"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
)
@ -18,7 +18,7 @@ import (
func (s *Server) UpdateDataStructure(data []byte) error {
src := new(Configuration)
if err := json.Unmarshal(data, src); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Don't allow obviously corrupted data to pass through into this function. If the UUID
@ -47,7 +47,7 @@ func (s *Server) UpdateDataStructure(data []byte) error {
// Merge the new data object that we have received with the existing server data object
// and then save it to the disk so it is persistent.
if err := mergo.Merge(&c, src, mergo.WithOverride); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Don't explode if we're setting CPU limits to 0. Mergo sees that as an empty value
@ -65,7 +65,7 @@ func (s *Server) UpdateDataStructure(data []byte) error {
// request is going to be boolean. Allegedly.
if v, err := jsonparser.GetBoolean(data, "container", "oom_disabled"); err != nil {
if err != jsonparser.KeyPathNotFoundError {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else {
c.Build.OOMDisabled = v
@ -74,7 +74,7 @@ func (s *Server) UpdateDataStructure(data []byte) error {
// Mergo also cannot handle this boolean value.
if v, err := jsonparser.GetBoolean(data, "suspended"); err != nil {
if err != jsonparser.KeyPathNotFoundError {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else {
c.Suspended = v
@ -82,7 +82,7 @@ func (s *Server) UpdateDataStructure(data []byte) error {
if v, err := jsonparser.GetBoolean(data, "skip_egg_scripts"); err != nil {
if err != jsonparser.KeyPathNotFoundError {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
} else {
c.SkipEggScripts = v

View File

@ -1,9 +1,9 @@
package sftp
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors"
"github.com/pkg/sftp"
"io"
"io/ioutil"
@ -58,14 +58,14 @@ func (fs FileSystem) Fileread(request *sftp.Request) (io.ReaderAt, error) {
if _, err := os.Stat(p); os.IsNotExist(err) {
return nil, sftp.ErrSshFxNoSuchFile
} else if err != nil {
fs.logger.WithField("error", errors.WithStack(err)).Error("error while processing file stat")
fs.logger.WithField("error", errors.WithStackIf(err)).Error("error while processing file stat")
return nil, sftp.ErrSshFxFailure
}
file, err := os.Open(p)
if err != nil {
fs.logger.WithField("source", p).WithField("error", errors.WithStack(err)).Error("could not open file for reading")
fs.logger.WithField("source", p).WithField("error", errors.WithStackIf(err)).Error("could not open file for reading")
return nil, sftp.ErrSshFxFailure
}
@ -108,7 +108,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
l.WithFields(log.Fields{
"path": filepath.Dir(p),
"error": errors.WithStack(err),
"error": errors.WithStackIf(err),
}).Error("error making path for file")
return nil, sftp.ErrSshFxFailure
@ -116,7 +116,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
file, err := os.Create(p)
if err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to create file")
l.WithField("error", errors.WithStackIf(err)).Error("failed to create file")
return nil, sftp.ErrSshFxFailure
}
@ -124,7 +124,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
// Not failing here is intentional. We still made the file, it is just owned incorrectly
// and will likely cause some issues.
if err := os.Chown(p, fs.User.Uid, fs.User.Gid); err != nil {
l.WithField("error", errors.WithStack(err)).Warn("failed to set permissions on file")
l.WithField("error", errors.WithStackIf(err)).Warn("failed to set permissions on file")
}
return file, nil
@ -133,7 +133,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
// If the stat error isn't about the file not existing, there is some other issue
// at play and we need to go ahead and bail out of the process.
if statErr != nil {
l.WithField("error", errors.WithStack(statErr)).Error("encountered error performing file stat")
l.WithField("error", errors.WithStackIf(statErr)).Error("encountered error performing file stat")
return nil, sftp.ErrSshFxFailure
}
@ -159,14 +159,14 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
return nil, sftp.ErrSSHFxNoSuchFile
}
l.WithField("flags", request.Flags).WithField("error", errors.WithStack(err)).Error("failed to open existing file on system")
l.WithField("flags", request.Flags).WithField("error", errors.WithStackIf(err)).Error("failed to open existing file on system")
return nil, sftp.ErrSshFxFailure
}
// Not failing here is intentional. We still made the file, it is just owned incorrectly
// and will likely cause some issues.
if err := os.Chown(p, fs.User.Uid, fs.User.Gid); err != nil {
l.WithField("error", errors.WithStack(err)).Warn("error chowning file")
l.WithField("error", errors.WithStackIf(err)).Warn("error chowning file")
}
return file, nil
@ -220,7 +220,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("error", errors.WithStack(err)).Error("failed to perform setstat on item")
l.WithField("error", errors.WithStackIf(err)).Error("failed to perform setstat on item")
return sftp.ErrSSHFxFailure
}
return nil
@ -234,7 +234,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("target", target).WithField("error", errors.WithStack(err)).Error("failed to rename file")
l.WithField("target", target).WithField("error", errors.WithStackIf(err)).Error("failed to rename file")
return sftp.ErrSshFxFailure
}
@ -246,7 +246,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.RemoveAll(p); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to remove directory")
l.WithField("error", errors.WithStackIf(err)).Error("failed to remove directory")
return sftp.ErrSshFxFailure
}
@ -258,7 +258,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.MkdirAll(p, 0755); err != nil {
l.WithField("error", errors.WithStack(err)).Error("failed to create directory")
l.WithField("error", errors.WithStackIf(err)).Error("failed to create directory")
return sftp.ErrSshFxFailure
}
@ -270,7 +270,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.Symlink(p, target); err != nil {
l.WithField("target", target).WithField("error", errors.WithStack(err)).Error("failed to create symlink")
l.WithField("target", target).WithField("error", errors.WithStackIf(err)).Error("failed to create symlink")
return sftp.ErrSshFxFailure
}
@ -286,7 +286,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("error", errors.WithStack(err)).Error("failed to remove a file")
l.WithField("error", errors.WithStackIf(err)).Error("failed to remove a file")
return sftp.ErrSshFxFailure
}
@ -305,7 +305,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
// and will likely cause some issues. There is no logical check for if the file was removed
// because both of those cases (Rmdir, Remove) have an explicit return rather than break.
if err := os.Chown(fileLocation, fs.User.Uid, fs.User.Gid); err != nil {
l.WithField("error", errors.WithStack(err)).Warn("error chowning file")
l.WithField("error", errors.WithStackIf(err)).Warn("error chowning file")
}
return sftp.ErrSshFxOk
@ -327,7 +327,7 @@ func (fs FileSystem) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
files, err := ioutil.ReadDir(p)
if err != nil {
fs.logger.WithField("error", errors.WithStack(err)).Error("error while listing directory")
fs.logger.WithField("error", errors.WithStackIf(err)).Error("error while listing directory")
return nil, sftp.ErrSshFxFailure
}
@ -342,7 +342,7 @@ func (fs FileSystem) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
if os.IsNotExist(err) {
return nil, sftp.ErrSshFxNoSuchFile
} else if err != nil {
fs.logger.WithField("source", p).WithField("error", errors.WithStack(err)).Error("error performing stat on file")
fs.logger.WithField("source", p).WithField("error", errors.WithStackIf(err)).Error("error performing stat on file")
return nil, sftp.ErrSshFxFailure
}

View File

@ -1,8 +1,8 @@
package sftp
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/server"
@ -28,14 +28,14 @@ func Initialize(config config.SystemConfiguration) error {
}
if err := New(s); err != nil {
return errors.WithStack(err)
return errors.WithStackIf(err)
}
// Initialize the SFTP server in a background thread since this is
// a long running operation.
go func(s *Server) {
if err := s.Initialize(); err != nil {
log.WithField("subsystem", "sftp").WithField("error", errors.WithStack(err)).Error("failed to initialize SFTP subsystem")
log.WithField("subsystem", "sftp").WithField("error", errors.WithStackIf(err)).Error("failed to initialize SFTP subsystem")
}
}(s)