diff --git a/api/api.go b/api/api.go index 4adb589..1860e37 100644 --- a/api/api.go +++ b/api/api.go @@ -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 diff --git a/api/backup_endpoints.go b/api/backup_endpoints.go index 6cd0617..87fe38c 100644 --- a/api/backup_endpoints.go +++ b/api/backup_endpoints.go @@ -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() diff --git a/api/server_endpoints.go b/api/server_endpoints.go index 6b402be..db1abee 100644 --- a/api/server_endpoints.go +++ b/api/server_endpoints.go @@ -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() diff --git a/api/sftp_endpoints.go b/api/sftp_endpoints.go index 5dbbfa6..bc480eb 100644 --- a/api/sftp_endpoints.go +++ b/api/sftp_endpoints.go @@ -1,8 +1,8 @@ package api import ( + "emperror.dev/errors" "github.com/apex/log" - "github.com/pkg/errors" "regexp" ) diff --git a/cmd/root.go b/cmd/root.go index fe92e6e..61533b2 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -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 { diff --git a/config/config.go b/config/config.go index 26b6e28..d2e2992 100644 --- a/config/config.go +++ b/config/config.go @@ -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 } diff --git a/config/config_docker.go b/config/config_docker.go index 3d561df..53b3908 100644 --- a/config/config_docker.go +++ b/config/config_docker.go @@ -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 diff --git a/config/config_system.go b/config/config_system.go index 8538645..9176403 100644 --- a/config/config_system.go +++ b/config/config_system.go @@ -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)) } diff --git a/environment/docker/container.go b/environment/docker/container.go index 148180d..a45ff2f 100644 --- a/environment/docker/container.go +++ b/environment/docker/container.go @@ -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 diff --git a/environment/docker/environment.go b/environment/docker/environment.go index d4aaf1c..1597b65 100644 --- a/environment/docker/environment.go +++ b/environment/docker/environment.go @@ -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 diff --git a/environment/docker/power.go b/environment/docker/power.go index 6544fef..a6305cc 100644 --- a/environment/docker/power.go +++ b/environment/docker/power.go @@ -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 { diff --git a/environment/docker/state.go b/environment/docker/state.go index 240eec5..ee03443 100644 --- a/environment/docker/state.go +++ b/environment/docker/state.go @@ -1,8 +1,8 @@ package docker import ( + "emperror.dev/errors" "fmt" - "github.com/pkg/errors" "github.com/pterodactyl/wings/environment" ) diff --git a/environment/docker/stats.go b/environment/docker/stats.go index ba4b367..c98f65e 100644 --- a/environment/docker/stats.go +++ b/environment/docker/stats.go @@ -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)) } diff --git a/environment/docker/stream.go b/environment/docker/stream.go index af02362..984eafd 100644 --- a/environment/docker/stream.go +++ b/environment/docker/stream.go @@ -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() diff --git a/events/events.go b/events/events.go index 3b5cc63..f8c3ffe 100644 --- a/events/events.go +++ b/events/events.go @@ -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)) diff --git a/go.mod b/go.mod index cecb97c..c09c340 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index 5c762cc..5c5eddc 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/installer/installer.go b/installer/installer.go index 4910e68..f400091 100644 --- a/installer/installer.go +++ b/installer/installer.go @@ -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()) diff --git a/loggers/cli/cli.go b/loggers/cli/cli.go index fab7368..e2d8b44 100644 --- a/loggers/cli/cli.go +++ b/loggers/cli/cli.go @@ -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 { diff --git a/parser/helpers.go b/parser/helpers.go index 9b6708e..b410e8b 100644 --- a/parser/helpers.go +++ b/parser/helpers.go @@ -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") diff --git a/parser/parser.go b/parser/parser.go index 8e0e5bd..ec4888e 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -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() diff --git a/router/error.go b/router/error.go index fdd90ea..63369de 100644 --- a/router/error.go +++ b/router/error.go @@ -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 } diff --git a/router/router_server.go b/router/router_server.go index 8b7669b..12d83a9 100644 --- a/router/router_server.go +++ b/router/router_server.go @@ -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()) diff --git a/router/router_server_files.go b/router/router_server_files.go index 7fd19e1..07e1d43 100644 --- a/router/router_server_files.go +++ b/router/router_server_files.go @@ -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,19 +35,19 @@ func getServerFileContents(c *gin.Context) { return } - c.Header("X-Mime-Type", st.Mimetype) - c.Header("Content-Length", strconv.Itoa(int(st.Info.Size()))) - - // If a download parameter is included in the URL go ahead and attach the necessary headers - // so that the file can be downloaded. - if c.Query("download") != "" { - 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 + } else { + c.Header("X-Mime-Type", st.Mimetype) + c.Header("Content-Length", strconv.Itoa(int(st.Info.Size()))) + + // If a download parameter is included in the URL go ahead and attach the necessary headers + // so that the file can be downloaded. + if c.Query("download") != "" { + c.Header("Content-Disposition", "attachment; filename="+st.Info.Name()) + c.Header("Content-Type", "application/octet-stream") + } } } @@ -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 diff --git a/router/router_transfer.go b/router/router_transfer.go index 3584a30..f2df212 100644 --- a/router/router_transfer.go +++ b/router/router_transfer.go @@ -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 } diff --git a/router/websocket/websocket.go b/router/websocket/websocket.go index c764be3..3a4620c 100644 --- a/router/websocket/websocket.go +++ b/router/websocket/websocket.go @@ -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{ diff --git a/server/archiver.go b/server/archiver.go index 35e6f05..951c6c9 100644 --- a/server/archiver.go +++ b/server/archiver.go @@ -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 diff --git a/server/backup.go b/server/backup.go index 9d8cd1f..c50003e 100644 --- a/server/backup.go +++ b/server/backup.go @@ -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 diff --git a/server/backup/archiver.go b/server/backup/archiver.go index 4dedccb..03d9db1 100644 --- a/server/backup/archiver.go +++ b/server/backup/archiver.go @@ -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 diff --git a/server/backup/backup.go b/server/backup/backup.go index 67006ce..5ba270a 100644 --- a/server/backup/backup.go +++ b/server/backup/backup.go @@ -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() diff --git a/server/backup/backup_local.go b/server/backup/backup_local.go index bc07bfe..45cb8a9 100644 --- a/server/backup/backup_local.go +++ b/server/backup/backup_local.go @@ -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 diff --git a/server/backup/backup_request.go b/server/backup/backup_request.go index a240596..ae14a1c 100644 --- a/server/backup/backup_request.go +++ b/server/backup/backup_request.go @@ -1,8 +1,8 @@ package backup import ( + "emperror.dev/errors" "fmt" - "github.com/pkg/errors" ) type Request struct { diff --git a/server/backup/backup_s3.go b/server/backup/backup_s3.go index 8dcf269..6476b72 100644 --- a/server/backup/backup_s3.go +++ b/server/backup/backup_s3.go @@ -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 diff --git a/server/console.go b/server/console.go index e6637ea..8d1736e 100644 --- a/server/console.go +++ b/server/console.go @@ -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 diff --git a/server/crash.go b/server/crash.go index 256d8bd..1200ff7 100644 --- a/server/crash.go +++ b/server/crash.go @@ -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 diff --git a/server/errors.go b/server/errors.go index 80fdaa9..2e8f50b 100644 --- a/server/errors.go +++ b/server/errors.go @@ -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 { } diff --git a/server/filesystem.go b/server/filesystem.go index c996938..c7aa643 100644 --- a/server/filesystem.go +++ b/server/filesystem.go @@ -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 { diff --git a/server/filesystem/compress.go b/server/filesystem/compress.go index fc2a4e2..c83e4d3 100644 --- a/server/filesystem/compress.go +++ b/server/filesystem/compress.go @@ -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) diff --git a/server/filesystem/decompress.go b/server/filesystem/decompress.go index 1c5cb3a..213282b 100644 --- a/server/filesystem/decompress.go +++ b/server/filesystem/decompress.go @@ -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 diff --git a/server/filesystem/disk_space.go b/server/filesystem/disk_space.go index 9efd2cc..8c0a7ff 100644 --- a/server/filesystem/disk_space.go +++ b/server/filesystem/disk_space.go @@ -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. diff --git a/server/filesystem/errors.go b/server/filesystem/errors.go index d2cb01e..e44ad53 100644 --- a/server/filesystem/errors.go +++ b/server/filesystem/errors.go @@ -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 = "" + } + 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() { @@ -32,4 +59,4 @@ func (fs *Filesystem) handleWalkerError(err error, f os.FileInfo) error { } return nil -} \ No newline at end of file +} diff --git a/server/filesystem/filesystem.go b/server/filesystem/filesystem.go index a6b89a5..be1cdc0 100644 --- a/server/filesystem/filesystem.go +++ b/server/filesystem/filesystem.go @@ -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. diff --git a/server/filesystem/filesystem_test.go b/server/filesystem/filesystem_test.go index a1a418b..49ab4f5 100644 --- a/server/filesystem/filesystem_test.go +++ b/server/filesystem/filesystem_test.go @@ -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() { diff --git a/server/filesystem/path.go b/server/filesystem/path.go index 6476a9d..8b3cd44 100644 --- a/server/filesystem/path.go +++ b/server/filesystem/path.go @@ -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 diff --git a/server/filesystem/stat.go b/server/filesystem/stat.go index 7896f9f..a9fdca4 100644 --- a/server/filesystem/stat.go +++ b/server/filesystem/stat.go @@ -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) } } diff --git a/server/install.go b/server/install.go index 0186591..0126b6b 100644 --- a/server/install.go +++ b/server/install.go @@ -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()) diff --git a/server/listeners.go b/server/listeners.go index 6284ae1..f9a3648 100644 --- a/server/listeners.go +++ b/server/listeners.go @@ -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 } diff --git a/server/loader.go b/server/loader.go index 6a8d1af..fd27938 100644 --- a/server/loader.go +++ b/server/loader.go @@ -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 diff --git a/server/power.go b/server/power.go index f9af920..49ff416 100644 --- a/server/power.go +++ b/server/power.go @@ -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") } } diff --git a/server/server.go b/server/server.go index 68f8b59..8eff4f2 100644 --- a/server/server.go +++ b/server/server.go @@ -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() diff --git a/server/state.go b/server/state.go index 3d6ae19..bc1e942 100644 --- a/server/state.go +++ b/server/state.go @@ -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 diff --git a/server/update.go b/server/update.go index f6261e6..41258ad 100644 --- a/server/update.go +++ b/server/update.go @@ -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 diff --git a/server/websockets.go b/server/websockets.go index ff7f441..bfa87fa 100644 --- a/server/websockets.go +++ b/server/websockets.go @@ -7,7 +7,7 @@ import ( ) type WebsocketBag struct { - mu sync.Mutex + mu sync.Mutex conns map[uuid.UUID]*context.CancelFunc } @@ -58,4 +58,4 @@ func (w *WebsocketBag) CancelAll() { // Reset the connections. w.conns = make(map[uuid.UUID]*context.CancelFunc) -} \ No newline at end of file +} diff --git a/sftp/handler.go b/sftp/handler.go index 04e46c4..e0e37f3 100644 --- a/sftp/handler.go +++ b/sftp/handler.go @@ -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 } diff --git a/sftp/sftp.go b/sftp/sftp.go index dcd870f..3c73f0b 100644 --- a/sftp/sftp.go +++ b/sftp/sftp.go @@ -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)