Error handling improvements (#71)

* Remove `emperror.dev/errors`, remove all `errors#Wrap` and `errors#WithStack` calls
* Improve logging in `server/backup.go`
This commit is contained in:
Matthew Penner 2020-11-28 16:57:10 -07:00 committed by GitHub
parent 40c70673cd
commit de51fd1c51
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 326 additions and 339 deletions

View File

@ -2,10 +2,10 @@ package api
import (
"bytes"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"io"
@ -69,7 +69,7 @@ func (r *Request) Endpoint(endpoint string) string {
func (r *Request) Make(method, url string, body io.Reader, opts ...func(r *http.Request)) (*Response, error) {
req, err := http.NewRequest(method, url, body)
if err != nil {
return nil, errors.WithStackIf(err)
return nil, 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.WithStackIf(err)
return nil, 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.WithStackIf(err)
return err
}
return errors.WithStackIf(json.Unmarshal(b, &v))
return json.Unmarshal(b, &v)
}
// Returns the error message from the API call as a string. The error message will be formatted

View File

@ -1,7 +1,6 @@
package api
import (
"emperror.dev/errors"
"fmt"
"strconv"
)
@ -16,7 +15,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.WithStackIf(err)
return nil, err
}
defer resp.Body.Close()
@ -26,7 +25,7 @@ func (r *Request) GetBackupRemoteUploadURLs(backup string, size int64) (*BackupR
var res BackupRemoteUploadResponse
if err := resp.Bind(&res); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
return &res, nil
@ -44,7 +43,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.WithStackIf(err)
return err
}
defer resp.Body.Close()

View File

@ -2,7 +2,6 @@ package api
import (
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
@ -57,7 +56,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.WithStackIf(err)
return nil, err
}
defer resp.Body.Close()
@ -67,7 +66,7 @@ func (r *Request) GetServers() ([]RawServerData, error) {
var res allServerResponse
if err := resp.Bind(&res); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
var mu sync.Mutex
@ -117,7 +116,7 @@ func (r *Request) GetServers() ([]RawServerData, error) {
}
if err := g.Wait(); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
}
@ -130,7 +129,7 @@ func (r *Request) GetServerConfiguration(uuid string) (ServerConfigurationRespon
resp, err := r.Get(fmt.Sprintf("/servers/%s", uuid), nil)
if err != nil {
return cfg, errors.WithStackIf(err)
return cfg, err
}
defer resp.Body.Close()
@ -139,7 +138,7 @@ func (r *Request) GetServerConfiguration(uuid string) (ServerConfigurationRespon
}
if err := resp.Bind(&cfg); err != nil {
return cfg, errors.WithStackIf(err)
return cfg, err
}
return cfg, nil
@ -150,7 +149,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.WithStackIf(err)
return is, err
}
defer resp.Body.Close()
@ -159,7 +158,7 @@ func (r *Request) GetInstallationScript(uuid string) (InstallationScript, error)
}
if err := resp.Bind(&is); err != nil {
return is, errors.WithStackIf(err)
return is, err
}
return is, nil
@ -169,7 +168,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.WithStackIf(err)
return err
}
defer resp.Body.Close()
@ -183,7 +182,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.WithStackIf(err)
return err
}
defer resp.Body.Close()
@ -193,7 +192,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.WithStackIf(err)
return err
}
defer resp.Body.Close()
@ -203,7 +202,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.WithStackIf(err)
return err
}
defer resp.Body.Close()

View File

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

View File

@ -18,9 +18,9 @@ import (
"github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/terminal"
"github.com/docker/cli/components/engine/pkg/parsers/operatingsystem"
"github.com/docker/docker/api/types"
"github.com/docker/docker/pkg/parsers/kernel"
"github.com/docker/docker/pkg/parsers/operatingsystem"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"github.com/spf13/cobra"

View File

@ -19,7 +19,7 @@ import (
"github.com/pterodactyl/wings/loggers/cli"
"golang.org/x/crypto/acme/autocert"
"emperror.dev/errors"
"github.com/pkg/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.WithStackIf(err)
return nil, 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.WithStackIf(err)).Error("failed to retrieve locally cached server states from disk, assuming all servers in offline state")
log.WithField("error", 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.WithStackIf(err)).Warn("failed to return server to running state")
s.Log().WithField("error", 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.WithStackIf(err)).Warn("failed to attach to running server environment")
s.Log().WithField("error", err).Warn("failed to attach to running server environment")
}
} else {
// At this point we've determined that the server should indeed be in an offline state, so we'll
@ -368,13 +368,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.WithStackIf(err)
return err
}
p := filepath.Join(logDir, "/wings.log")
w, err := logrotate.NewFile(p)
if err != nil {
panic(errors.WrapIf(err, "failed to open process log file"))
panic(errors.WithMessage(err, "failed to open process log file"))
}
if debug {

View File

@ -1,11 +1,11 @@
package config
import (
"emperror.dev/errors"
"fmt"
"github.com/cobaugh/osrelease"
"github.com/creasty/defaults"
"github.com/gbrlsnchs/jwt/v3"
"github.com/pkg/errors"
"gopkg.in/yaml.v2"
"io/ioutil"
"os"
@ -192,7 +192,7 @@ func GetJwtAlgorithm() *jwt.HMACSHA {
func NewFromPath(path string) (*Configuration, error) {
c := new(Configuration)
if err := defaults.Set(c); err != nil {
return c, errors.WithStackIf(err)
return c, err
}
c.unsafeSetPath(path)
@ -230,12 +230,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.WithStackIf(err)
return nil, err
}
sysName, err := getSystemName()
if err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
var command = fmt.Sprintf("useradd --system --no-create-home --shell /bin/false %s", c.System.Username)
@ -248,17 +248,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.WithStackIf(err)
return nil, err
}
}
split := strings.Split(command, " ")
if _, err := exec.Command(split[0], split[1:]...).Output(); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
if u, err := user.Lookup(c.System.Username); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
} else {
return u, c.setSystemUser(u)
}
@ -300,11 +300,11 @@ func (c *Configuration) WriteToDisk() error {
b, err := yaml.Marshal(&ccopy)
if err != nil {
return errors.WithStackIf(err)
return err
}
if err := ioutil.WriteFile(c.GetPath(), b, 0644); err != nil {
return errors.WithStackIf(err)
return err
}
return nil
@ -314,7 +314,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.WithStackIf(err)
return "", err
} else {
return release["ID"], nil
}

View File

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

View File

@ -2,9 +2,9 @@ package config
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"html/template"
"io/ioutil"
"os"
@ -98,7 +98,7 @@ func (sc *SystemConfiguration) ConfigureDirectories() error {
// that.
if d, err := filepath.EvalSymlinks(sc.Data); err != nil {
if !os.IsNotExist(err) {
return errors.WithStackIf(err)
return err
}
} else if d != sc.Data {
sc.Data = d
@ -134,13 +134,13 @@ func (sc *SystemConfiguration) EnableLogRotation() error {
}
if st, err := os.Stat("/etc/logrotate.d"); err != nil && !os.IsNotExist(err) {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return err
} else if err == nil {
return nil
}
@ -151,7 +151,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.WithStackIf(err)
return err
}
defer f.Close()
@ -171,10 +171,10 @@ func (sc *SystemConfiguration) EnableLogRotation() error {
}`)
if err != nil {
return errors.WithStackIf(err)
return err
}
return errors.WrapIf(t.Execute(f, sc), "failed to write logrotate file to disk")
return errors.WithMessage(t.Execute(f, sc), "failed to write logrotate file to disk")
}
// Returns the location of the JSON file that tracks server states.
@ -194,7 +194,7 @@ func (sc *SystemConfiguration) ConfigureTimezone() error {
if sc.Timezone == "" {
if b, err := ioutil.ReadFile("/etc/timezone"); err != nil {
if !os.IsNotExist(err) {
return errors.WrapIf(err, "failed to open /etc/timezone for automatic server timezone calibration")
return errors.WithMessage(err, "failed to open /etc/timezone for automatic server timezone calibration")
}
ctx, _ := context.WithTimeout(context.Background(), time.Second*5)
@ -228,5 +228,5 @@ func (sc *SystemConfiguration) ConfigureTimezone() error {
_, err := time.LoadLocation(sc.Timezone)
return errors.WrapIf(err, fmt.Sprintf("the supplied timezone %s is invalid", sc.Timezone))
return errors.WithMessage(err, fmt.Sprintf("the supplied timezone %s is invalid", sc.Timezone))
}

View File

@ -4,7 +4,6 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
@ -13,6 +12,7 @@ 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
} else {
e.SetStream(&st)
}
@ -72,7 +72,7 @@ func (e *Environment) Attach() error {
if err := e.pollResources(ctx); err != nil {
l := log.WithField("environment_id", e.Id)
if !errors.Is(err, context.Canceled) {
l.WithField("error", errors.WithStackIf(err)).Error("error during environment resource polling")
l.WithField("error", err).Error("error during environment resource polling")
} else {
l.Warn("stopping server resource polling: context canceled")
}
@ -82,7 +82,7 @@ func (e *Environment) Attach() error {
// 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.WithStackIf(err)).Error("error while copying environment output to console")
log.WithField("environment_id", e.Id).WithField("error", err).Error("error while copying environment output to console")
}
}(c)
@ -120,7 +120,7 @@ func (e *Environment) InSituUpdate() error {
return nil
}
return errors.WithStackIf(err)
return err
}
u := container.UpdateConfig{
@ -130,7 +130,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.WithStackIf(err)
return err
}
return nil
@ -145,12 +145,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.WithStackIf(err)
return err
}
// Try to pull the requested image before creating the container.
if err := e.ensureImageExists(e.meta.Image); err != nil {
return errors.WithStackIf(err)
return err
}
a := e.Configuration.Allocations()
@ -225,7 +225,7 @@ func (e *Environment) Create() error {
}
if _, err := e.client.ContainerCreate(context.Background(), conf, hostConf, nil, e.Id); err != nil {
return errors.WithStackIf(err)
return err
}
return nil
@ -277,7 +277,7 @@ func (e *Environment) Destroy() error {
func (e *Environment) followOutput() error {
if exists, err := e.Exists(); !exists {
if err != nil {
return errors.WithStackIf(err)
return err
}
return errors.New(fmt.Sprintf("no such container: %s", e.Id))
@ -302,7 +302,6 @@ func (e *Environment) followOutput() error {
cr := []byte(" \r")
crr := []byte("\r\n")
// Avoid constantly re-allocating memory when we're flooding lines through this
// function by using the same buffer for the duration of the call and just truncating
// the value back to 0 every loop.
@ -354,7 +353,7 @@ func (e *Environment) followOutput() error {
}
}(reader)
return errors.WithStackIf(err)
return err
}
// Pulls the image from Docker. If there is an error while pulling the image from the source

View File

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

View File

@ -2,11 +2,11 @@ package docker
import (
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/environment"
"os"
@ -26,7 +26,7 @@ func (e *Environment) OnBeforeStart() error {
// the Panel is usee.
if err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{RemoveVolumes: true}); err != nil {
if !client.IsErrNotFound(err) {
return errors.WrapIf(err, "failed to remove server docker container during pre-boot")
return errors.WithMessage(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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(seconds)*time.Second)
@ -185,10 +185,10 @@ func (e *Environment) WaitForStop(seconds uint, terminate bool) error {
if terminate {
log.WithField("container_id", e.Id).Info("server did not stop in time, executing process termination")
return errors.WithStackIf(e.Terminate(os.Kill))
return e.Terminate(os.Kill)
}
return errors.WithStackIf(ctxErr)
return ctxErr
}
case err := <-errChan:
if err != nil {
@ -197,13 +197,13 @@ func (e *Environment) WaitForStop(seconds uint, terminate bool) error {
if errors.Is(err, context.DeadlineExceeded) {
l.Warn("deadline exceeded for container stop; terminating process")
} else {
l.WithField("error", errors.WithStackIf(err)).Warn("error while waiting for container stop; terminating process")
l.WithField("error", err).Warn("error while waiting for container stop; terminating process")
}
return errors.WithStackIf(e.Terminate(os.Kill))
return e.Terminate(os.Kill)
}
return errors.WithStackIf(err)
return err
}
case <-ok:
}
@ -215,7 +215,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.WithStackIf(err)
return err
}
if !c.State.Running {

View File

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

View File

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

View File

@ -4,9 +4,9 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"encoding/json"
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
"strconv"
)
@ -15,7 +15,7 @@ type dockerLogLine struct {
Log string `json:"log"`
}
var ErrNotAttached = errors.Sentinel("not attached to instance")
var ErrNotAttached = errors.New("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.WithStackIf(err)
return 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.WithStackIf(err)
return nil, err
}
defer r.Close()

View File

@ -1,7 +1,6 @@
package events
import (
"emperror.dev/errors"
"encoding/json"
"github.com/gammazero/workerpool"
"strings"
@ -69,7 +68,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.WithStackIf(err)
return err
}
e.Publish(topic, string(b))

3
go.mod
View File

@ -3,7 +3,6 @@ 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
@ -18,7 +17,6 @@ require (
github.com/containerd/containerd v1.3.7 // indirect
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b // indirect
github.com/creasty/defaults v1.5.0
github.com/docker/cli v17.12.1-ce-rc2+incompatible
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible
github.com/docker/go-connections v0.4.0
@ -58,6 +56,7 @@ 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

8
go.sum
View File

@ -1,7 +1,5 @@
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=
@ -95,8 +93,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/docker/cli v17.12.1-ce-rc2+incompatible h1:ESUycEAqvFuLglAHkUW66rCc2djYtd3i1x231svLq9o=
github.com/docker/cli v17.12.1-ce-rc2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8=
@ -563,13 +559,9 @@ go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.1.0 h1:HoEmRHQPVSqub6w2z2d2EOVs2fjyFRGyofhKuyDq0QI=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=

View File

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

View File

@ -1,12 +1,12 @@
package cli
import (
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/apex/log/handlers/cli"
color2 "github.com/fatih/color"
"github.com/mattn/go-colorable"
"github.com/pkg/errors"
"io"
"os"
"sync"
@ -88,7 +88,7 @@ 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.
if e, ok = errors.WrapIf(err, "failed to generate stacktrace for caught error").(tracer); ok {
if e, ok = errors.WithMessage(err, "failed to generate stacktrace for caught error").(tracer); ok {
return e.StackTrace()
}
@ -98,7 +98,7 @@ func getErrorStack(err error, i bool) errors.StackTrace {
return nil
}
return getErrorStack(errors.WrapIf(err, err.Error()), true)
return getErrorStack(errors.WithMessage(err, err.Error()), true)
}
st := e.StackTrace()

View File

@ -2,11 +2,11 @@ package parser
import (
"bytes"
"emperror.dev/errors"
"github.com/Jeffail/gabs/v2"
"github.com/apex/log"
"github.com/buger/jsonparser"
"github.com/iancoleman/strcase"
"github.com/pkg/errors"
"io/ioutil"
"os"
"regexp"
@ -76,13 +76,13 @@ func (cfr *ConfigurationFileReplacement) getKeyValue(value []byte) interface{} {
func (f *ConfigurationFile) IterateOverJson(data []byte) (*gabs.Container, error) {
parsed, err := gabs.ParseJSON(data)
if err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
for _, v := range f.Replace {
value, err := f.LookupConfigurationValue(v)
if err != nil {
return nil, errors.WithStackIf(err)
return nil, 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.WrapIf(err, "failed to set config value of array child")
return nil, errors.WithMessage(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.WrapIf(err, "unable to set config value at pathway: "+v.Match)
return nil, errors.WithMessage(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.WithStackIf(err)
return 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.WrapIf(err, "error while parsing array element at path")
return errors.WithMessage(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.WrapIf(err, "failed to create empty array for missing element")
return errors.WithMessage(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.WrapIf(err, "failed to find array element at path")
return errors.WithMessage(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.WrapIf(err, "failed to set value at config path: "+path)
return errors.WithMessage(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.WithStackIf(err)
return string(match), err
}
log.WithFields(log.Fields{"path": path, "filename": f.FileName}).Debug("attempted to load a configuration value that does not exist")

View File

@ -2,13 +2,13 @@ package parser
import (
"bufio"
"emperror.dev/errors"
"encoding/json"
"github.com/apex/log"
"github.com/beevik/etree"
"github.com/buger/jsonparser"
"github.com/icza/dyno"
"github.com/magiconair/properties"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"gopkg.in/ini.v1"
"gopkg.in/yaml.v2"
@ -166,17 +166,17 @@ func (f *ConfigurationFile) Parse(path string, internal bool) error {
b := strings.TrimSuffix(path, filepath.Base(path))
if err := os.MkdirAll(b, 0755); err != nil {
return errors.WrapIf(err, "failed to create base directory for missing configuration file")
return errors.WithMessage(err, "failed to create base directory for missing configuration file")
} else {
if _, err := os.Create(path); err != nil {
return errors.WrapIf(err, "failed to create missing configuration file")
return errors.WithMessage(err, "failed to create missing configuration file")
}
}
return f.Parse(path, true)
}
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
i := make(map[string]interface{})
if err := yaml.Unmarshal(b, &i); err != nil {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
// Decode the properties file.
p, err := properties.LoadFile(path, properties.UTF8)
if err != nil {
return errors.WithStackIf(err)
return err
}
// Replace any values that need to be replaced.
for _, replace := range f.Replace {
data, err := f.LookupConfigurationValue(replace)
if err != nil {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
defer w.Close()

View File

@ -1,11 +1,11 @@
package router
import (
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
"net/http"
@ -75,7 +75,7 @@ func (e *RequestError) AbortWithStatus(status int, c *gin.Context) {
if status >= 500 {
e.logger().WithField("error", e.Err).Error("encountered HTTP/500 error while handling request")
c.Error(errors.WithStackIf(e))
c.Error(e)
} else {
e.logger().WithField("error", e.Err).Debug("encountered non-HTTP/500 error while handling request")
}

View File

@ -3,9 +3,9 @@ package router
import (
"bytes"
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"net/http"
@ -227,7 +227,7 @@ func deleteServer(c *gin.Context) {
if err := os.RemoveAll(p); err != nil {
log.WithFields(log.Fields{
"path": p,
"error": errors.WithStackIf(err),
"error": err,
}).Warn("failed to remove server files during deletion process")
}
}(s.Filesystem().Path())
@ -247,7 +247,9 @@ func deleteServer(c *gin.Context) {
// preventing any JWT generated before the current time from being used to connect to
// the socket or send along commands.
func postServerDenyWSTokens(c *gin.Context) {
var data struct{ JTIs []string `json:"jtis"` }
var data struct {
JTIs []string `json:"jtis"`
}
if err := c.BindJSON(&data); err != nil {
return

View File

@ -2,8 +2,8 @@ package router
import (
"context"
"emperror.dev/errors"
"github.com/gin-gonic/gin"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"github.com/pterodactyl/wings/server/filesystem"
@ -422,12 +422,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.WithStackIf(err)
return err
}
defer file.Close()
if err := s.Filesystem().Writefile(p, file); err != nil {
return errors.WithStackIf(err)
return err
}
return nil

View File

@ -4,12 +4,12 @@ import (
"bufio"
"bytes"
"crypto/sha256"
"emperror.dev/errors"
"encoding/hex"
"github.com/apex/log"
"github.com/buger/jsonparser"
"github.com/gin-gonic/gin"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/installer"
@ -157,7 +157,7 @@ func postTransfer(c *gin.Context) {
// Make a new GET request to the URL the panel gave us.
req, err := http.NewRequest("GET", url, nil)
if err != nil {
log.WithField("error", errors.WithStackIf(err)).Error("failed to create http request for archive transfer")
log.WithField("error", 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.WithStackIf(err)).Error("failed to send archive http request")
l.WithField("error", 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.WithStackIf(err)).WithField("status", res.StatusCode).Error("failed read transfer response body")
l.WithField("error", err).WithField("status", res.StatusCode).Error("failed read transfer response body")
return
}
l.WithField("error", errors.WithStackIf(err)).WithField("status", res.StatusCode).Error("failed to request server archive")
l.WithField("error", 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.WithStackIf(err)).Error("failed to stat archive file")
l.WithField("error", err).Error("failed to stat archive file")
return
}
} else {
if err := os.Remove(archivePath); err != nil {
l.WithField("error", errors.WithStackIf(err)).Warn("failed to remove old archive file")
l.WithField("error", 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.WithStackIf(err)).Error("failed to open archive on disk")
l.WithField("error", 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.WithStackIf(err)).Error("failed to copy archive file to disk")
l.WithField("error", 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.WithStackIf(err)).Error("failed to close archive file")
l.WithField("error", 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.WithStackIf(err)).Error("failed to open archive on disk")
l.WithField("error", 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.WithStackIf(err)).Error("failed to copy archive file for checksum verification")
l.WithField("error", 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.WithStackIf(err)).Error("failed to close archive file after calculating checksum")
l.WithField("error", 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.WithStackIf(err)).Error("failed to validate received server data")
l.WithField("error", 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.WithStackIf(err)).Error("failed to extract server archive")
l.WithField("error", err).Error("failed to extract server archive")
return
}
@ -299,12 +299,11 @@ func postTransfer(c *gin.Context) {
err = api.New().SendTransferSuccess(serverID)
if err != nil {
if !api.IsRequestError(err) {
l.WithField("error", errors.WithStackIf(err)).Error("failed to notify panel of transfer success")
l.WithField("error", err).Error("failed to notify panel of transfer success")
return
}
l.WithField("error", err.Error()).Error("panel responded with error after transfer success")
return
}

View File

@ -2,13 +2,13 @@ package websocket
import (
"context"
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/gbrlsnchs/jwt/v3"
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/environment/docker"
@ -41,10 +41,10 @@ type Handler struct {
}
var (
ErrJwtNotPresent = errors.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)")
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)")
)
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.WithStackIf(err)
return nil, err
}
return &Handler{

View File

@ -2,9 +2,9 @@ package server
import (
"crypto/sha256"
"emperror.dev/errors"
"encoding/hex"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/server/filesystem"
"io"
@ -41,7 +41,7 @@ func (a *Archiver) Exists() bool {
func (a *Archiver) Stat() (*filesystem.Stat, error) {
s, err := os.Stat(a.Path())
if err != nil {
return nil, errors.WithStack(err)
return nil, err
}
return &filesystem.Stat{
@ -58,7 +58,7 @@ func (a *Archiver) Archive() error {
var files []string
fileInfo, err := ioutil.ReadDir(path)
if err != nil {
return errors.WithStack(err)
return err
}
for _, file := range fileInfo {
@ -94,17 +94,17 @@ func (a *Archiver) DeleteIfExists() error {
return nil
}
return errors.WithStackIf(err)
return err
}
return errors.WrapIf(os.Remove(a.Path()), "archiver: failed to delete archive from system")
return errors.WithMessage(os.Remove(a.Path()), "archiver: failed to delete archive from system")
}
// Checksum computes a SHA256 checksum of the server's archive.
func (a *Archiver) Checksum() (string, error) {
file, err := os.Open(a.Path())
if err != nil {
return "", errors.WithStack(err)
return "", err
}
defer file.Close()
@ -112,7 +112,7 @@ func (a *Archiver) Checksum() (string, error) {
buf := make([]byte, 1024*4)
if _, err := io.CopyBuffer(hash, file, buf); err != nil {
return "", errors.WithStack(err)
return "", err
}
return hex.EncodeToString(hash.Sum(nil)), nil

View File

@ -2,8 +2,8 @@ package server
import (
"bufio"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/server/backup"
"os"
@ -21,7 +21,7 @@ func (s *Server) notifyPanelOfBackup(uuid string, ad *backup.ArchiveDetails, suc
"error": err,
}).Error("failed to notify panel of backup status due to wings error")
return errors.WithStackIf(err)
return err
}
return errors.New(err.Error())
@ -37,7 +37,7 @@ func (s *Server) getServerwideIgnoredFiles() ([]string, error) {
f, err := os.Open(path.Join(s.Filesystem().Path(), ".pteroignore"))
if err != nil {
if !os.IsNotExist(err) {
return nil, errors.WithStack(err)
return nil, err
}
} else {
scanner := bufio.NewScanner(f)
@ -49,7 +49,7 @@ func (s *Server) getServerwideIgnoredFiles() ([]string, error) {
}
if err := scanner.Err(); err != nil {
return nil, errors.WithStack(err)
return nil, err
}
}
@ -79,7 +79,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.WithStackIf(err)
return err
}
ad, err := b.Generate(inc, s.Filesystem().Path())
@ -89,6 +89,11 @@ func (s *Server) Backup(b backup.BackupInterface) error {
"backup": b.Identifier(),
"error": notifyError,
}).Warn("failed to notify panel of failed backup state")
} else {
s.Log().WithFields(log.Fields{
"backup": b.Identifier(),
"error": err,
}).Info("notified panel of failed backup state")
}
s.Events().PublishJson(BackupCompletedEvent+":"+b.Identifier(), map[string]interface{}{
@ -99,15 +104,17 @@ func (s *Server) Backup(b backup.BackupInterface) error {
"file_size": 0,
})
return errors.WrapIf(err, "backup: error while generating server backup")
return errors.WithMessage(err, "backup: error while generating server backup")
}
// Try to notify the panel about the status of this backup. If for some reason this request
// fails, delete the archive from the daemon and return that error up the chain to the caller.
if notifyError := s.notifyPanelOfBackup(b.Identifier(), ad, true); notifyError != nil {
b.Remove()
return errors.WithStackIf(err)
s.Log().WithField("error", notifyError).Info("failed to notify panel of successful backup state")
return err
} else {
s.Log().WithField("backup", b.Identifier()).Info("notified panel of successful backup state")
}
// Emit an event over the socket so we can update the backup in realtime on

View File

@ -3,9 +3,9 @@ package backup
import (
"archive/tar"
"context"
"emperror.dev/errors"
"github.com/apex/log"
gzip "github.com/klauspost/pgzip"
"github.com/pkg/errors"
"github.com/remeh/sizedwaitgroup"
"golang.org/x/sync/errgroup"
"io"
@ -26,7 +26,7 @@ type Archive struct {
func (a *Archive) Create(dst string, ctx context.Context) error {
f, err := os.OpenFile(dst, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return errors.WithStackIf(err)
return err
}
defer f.Close()
@ -58,7 +58,7 @@ func (a *Archive) Create(dst string, ctx context.Context) error {
select {
case <-ctx.Done():
return errors.WithStackIf(ctx.Err())
return 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.WithStackIf(err)
return err
}
return nil
@ -91,7 +91,7 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
return nil
}
return errors.WithStackIf(err)
return err
}
defer f.Close()
@ -102,14 +102,15 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
return nil
}
return errors.WithStackIf(err)
return err
}
header, err := tar.FileInfoHeader(s, strings.TrimPrefix(p, a.TrimPrefix))
name := strings.TrimPrefix(p, a.TrimPrefix)
header, err := tar.FileInfoHeader(s, name)
if err != nil {
return errors.WithStackIf(err)
return errors.WithMessage(err, "failed to get tar#FileInfoHeader for "+name)
}
header.Name = strings.TrimPrefix(p, a.TrimPrefix)
header.Name = name
// These actions must occur sequentially, even if this function is called multiple
// in parallel. You'll get some nasty panic's otherwise.
@ -117,12 +118,12 @@ func (a *Archive) addToArchive(p string, w *tar.Writer) error {
defer a.Unlock()
if err := w.WriteHeader(header); err != nil {
return errors.WithStackIf(err)
return err
}
buf := make([]byte, 4*1024)
if _, err := io.CopyBuffer(w, io.LimitReader(f, header.Size), buf); err != nil {
return errors.WithStackIf(err)
return errors.WithMessage(err, "failed to copy "+header.Name+" to archive")
}
return nil

View File

@ -2,7 +2,6 @@ package backup
import (
"crypto/sha1"
"emperror.dev/errors"
"encoding/hex"
"github.com/apex/log"
"github.com/pterodactyl/wings/api"
@ -87,7 +86,7 @@ func (b *Backup) Path() string {
func (b *Backup) Size() (int64, error) {
st, err := os.Stat(b.Path())
if err != nil {
return 0, errors.WithStackIf(err)
return 0, err
}
return st.Size(), nil
@ -99,7 +98,7 @@ func (b *Backup) Checksum() ([]byte, error) {
f, err := os.Open(b.Path())
if err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
defer f.Close()
@ -128,6 +127,7 @@ func (b *Backup) Details() *ArchiveDetails {
"backup": b.Identifier(),
"error": err,
}).Error("failed to calculate checksum for backup")
return
}
checksum = hex.EncodeToString(resp)

View File

@ -2,7 +2,7 @@ package backup
import (
"context"
"emperror.dev/errors"
"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.WithStackIf(err)
return nil, nil, 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.WithStackIf(err)
return nil, err
}
return b.Details(), nil

View File

@ -1,7 +1,7 @@
package backup
import (
"emperror.dev/errors"
"errors"
"fmt"
)

View File

@ -3,7 +3,6 @@ package backup
import (
"bytes"
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pterodactyl/wings/api"
@ -31,20 +30,20 @@ func (s *S3Backup) Generate(included *IncludedFiles, prefix string) (*ArchiveDet
}
if err := a.Create(s.Path(), context.Background()); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
rc, err := os.Open(s.Path())
if err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
defer rc.Close()
if err := s.generateRemoteRequest(rc); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
return s.Details(), err
return s.Details(), nil
}
// Removes a backup from the system.

View File

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

View File

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

View File

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

View File

@ -1,7 +1,6 @@
package server
import (
"emperror.dev/errors"
"github.com/pterodactyl/wings/server/filesystem"
"os"
)
@ -13,12 +12,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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
if err := s.fs.Chown("/"); err != nil {

View File

@ -2,7 +2,6 @@ package filesystem
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/karrick/godirwalk"
"github.com/pterodactyl/wings/server/backup"
@ -27,7 +26,7 @@ func (fs *Filesystem) GetIncludedFiles(dir string, ignored []string) (*backup.In
i, err := ignore.CompileIgnoreLines(ignored...)
if err != nil {
return nil, errors.WithStack(err)
return nil, err
}
// Walk through all of the files and directories on a server. This callback only returns
@ -65,7 +64,7 @@ func (fs *Filesystem) GetIncludedFiles(dir string, ignored []string) (*backup.In
},
})
return inc, errors.WithStackIf(err)
return inc, err
}
// Compresses all of the files matching the given paths in the specified directory. This function
@ -141,7 +140,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.WithStackIf(err)
return nil, err
}
f, err := os.Stat(d)

View File

@ -4,9 +4,9 @@ import (
"archive/tar"
"archive/zip"
"compress/gzip"
"emperror.dev/errors"
"fmt"
"github.com/mholt/archiver/v3"
"github.com/pkg/errors"
"os"
"path/filepath"
"reflect"
@ -47,10 +47,10 @@ func (fs *Filesystem) SpaceAvailableForDecompression(dir string, file string) (b
return false, ErrUnknownArchiveFormat
}
return false, errors.WithStackIf(err)
return false, err
}
return true, errors.WithStackIf(err)
return true, 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.WithStackIf(err)
return err
}
// Make sure the file exists basically.
if _, err := os.Stat(source); err != nil {
return errors.WithStackIf(err)
return 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.WrapIf(err, "failed to generate a safe path to server file")
return errors.WithMessage(err, "failed to generate a safe path to server file")
}
return errors.WrapIf(fs.Writefile(p, f), "could not extract file from archive")
return errors.WithMessage(fs.Writefile(p, f), "could not extract file from archive")
})
if err != nil {
if strings.HasPrefix(err.Error(), "format ") {
return errors.WithStackIf(ErrUnknownArchiveFormat)
return ErrUnknownArchiveFormat
}
return errors.WithStackIf(err)
return err
}
return nil

View File

@ -1,7 +1,6 @@
package filesystem
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/karrick/godirwalk"
"sync"
@ -158,7 +157,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.WithStackIf(err)
return 0, err
}
var size int64
@ -189,7 +188,7 @@ func (fs *Filesystem) DirectorySize(dir string) (int64, error) {
},
})
return size, errors.WithStackIf(err)
return size, err
}
// Helper function to determine if a server has space available for a file of a given size.
@ -202,7 +201,7 @@ func (fs *Filesystem) hasSpaceFor(size int64) error {
s, err := fs.DiskUsage(true)
if err != nil {
return errors.WithStackIf(err)
return err
}
if (s + size) > fs.MaxDisk() {

View File

@ -1,16 +1,16 @@
package filesystem
import (
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"os"
"path/filepath"
)
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")
var ErrIsDirectory = errors.New("filesystem: is a directory")
var ErrNotEnoughDiskSpace = errors.New("filesystem: not enough disk space")
var ErrUnknownArchiveFormat = errors.New("filesystem: unknown archive format")
type BadPathResolutionError struct {
path string
@ -23,6 +23,7 @@ func (b *BadPathResolutionError) Error() string {
if r == "" {
r = "<empty>"
}
return fmt.Sprintf("filesystem: server path [%s] resolves to a location outside the server root: %s", b.path, r)
}
@ -57,7 +58,7 @@ func (fs *Filesystem) error(err error) *log.Entry {
// 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 !IsBadPathResolutionError(err) {
return errors.WithStackIf(err)
return err
}
if f != nil && f.IsDir() {

View File

@ -2,9 +2,9 @@ package filesystem
import (
"bufio"
"emperror.dev/errors"
"github.com/gabriel-vasile/mimetype"
"github.com/karrick/godirwalk"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"io"
@ -60,27 +60,27 @@ func (fs *Filesystem) Readfile(p string, w io.Writer) error {
}
if st, err := os.Stat(cleaned); err != nil {
return errors.WithStack(err)
return err
} else if st.IsDir() {
return errors.WithStack(ErrIsDirectory)
return ErrIsDirectory
}
f, err := os.Open(cleaned)
if err != nil {
return errors.WithStack(err)
return err
}
defer f.Close()
_, err = bufio.NewReader(f).WriteTo(w)
return errors.WithStack(err)
return err
}
// Writes a file to the system. If the file does not already exist one will be created.
func (fs *Filesystem) Writefile(p string, r io.Reader) error {
cleaned, err := fs.SafePath(p)
if err != nil {
return errors.WithStackIf(err)
return err
}
var currentSize int64
@ -88,19 +88,19 @@ 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.WithStackIf(err)
return err
}
if err := os.MkdirAll(filepath.Dir(cleaned), 0755); err != nil {
return errors.WithStackIf(err)
return err
}
if err := fs.Chown(filepath.Dir(cleaned)); err != nil {
return errors.WithStackIf(err)
return err
}
} else {
if stat.IsDir() {
return errors.WithStack(ErrIsDirectory)
return ErrIsDirectory
}
currentSize = stat.Size()
@ -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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
cleanedTo, err := fs.SafePath(to)
if err != nil {
return errors.WithStackIf(err)
return 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.WrapIf(mkerr, "failed to create directory structure for file rename")
return errors.WithMessage(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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
// If this is not a directory we can now return from the function, there is nothing
@ -249,7 +249,7 @@ func (fs *Filesystem) findCopySuffix(dir string, name string, extension string)
// does exist, we'll just continue to the next loop and try again.
if _, err := fs.Stat(path.Join(dir, n)); err != nil {
if !errors.Is(err, os.ErrNotExist) {
return "", errors.WithStackIf(err)
return "", err
}
break
@ -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.WithStackIf(err)
return err
}
s, err := os.Stat(cleaned)
if err != nil {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
defer source.Close()

View File

@ -2,7 +2,6 @@ package filesystem
import (
"context"
"emperror.dev/errors"
"golang.org/x/sync/errgroup"
"os"
"path/filepath"
@ -26,7 +25,7 @@ func (fs *Filesystem) SafePath(p string) (string, error) {
// is truly pointing to.
ep, err := filepath.EvalSymlinks(r)
if err != nil && !os.IsNotExist(err) {
return "", errors.WithStackIf(err)
return "", 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.
@ -138,5 +137,5 @@ func (fs *Filesystem) ParallelSafePath(paths []string) ([]string, error) {
}
// Block until all of the routines finish and have returned a value.
return cleaned, errors.WithStackIf(g.Wait())
return cleaned, g.Wait()
}

View File

@ -2,8 +2,8 @@ package filesystem
import (
"bytes"
"emperror.dev/errors"
. "github.com/franela/goblin"
"github.com/pkg/errors"
"os"
"path/filepath"
"testing"

View File

@ -1,7 +1,6 @@
package filesystem
import (
"emperror.dev/errors"
"encoding/json"
"github.com/gabriel-vasile/mimetype"
"os"
@ -51,14 +50,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, errors.WithStackIf(err)
return nil, err
}
var m *mimetype.MIME
if !s.IsDir() {
m, err = mimetype.DetectFile(p)
if err != nil {
return nil, errors.WithStackIf(err)
return nil, err
}
}

View File

@ -4,12 +4,12 @@ import (
"bufio"
"bytes"
"context"
"emperror.dev/errors"
"github.com/apex/log"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/mount"
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -91,7 +91,7 @@ func (s *Server) internalInstall() error {
script, err := api.New().GetInstallationScript(s.Id())
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStackIf(err)
return err
}
return errors.New(err.Error())
@ -99,7 +99,7 @@ func (s *Server) internalInstall() error {
p, err := NewInstallationProcess(s, &script)
if err != nil {
return errors.WithStackIf(err)
return err
}
s.Log().Info("beginning installation process for server")
@ -131,7 +131,7 @@ func NewInstallationProcess(s *Server, script *api.InstallationScript) (*Install
s.installer.cancel = &cancel
if c, err := environment.DockerClient(); err != nil {
return nil, errors.WithStackIf(err)
return nil, err
} else {
proc.client = c
proc.context = ctx
@ -194,7 +194,7 @@ func (ip *InstallationProcess) RemoveContainer() {
})
if err != nil && !client.IsErrNotFound(err) {
ip.Server.Log().WithField("error", errors.WithStackIf(err)).Warn("failed to delete server install container")
ip.Server.Log().WithField("error", err).Warn("failed to delete server install container")
}
}
@ -219,14 +219,14 @@ func (ip *InstallationProcess) Run() error {
}()
if err := ip.BeforeExecute(); err != nil {
return errors.WithStackIf(err)
return err
}
cid, err := ip.Execute()
if err != nil {
ip.RemoveContainer()
return errors.WithStackIf(err)
return err
}
// If this step fails, log a warning but don't exit out of the process. This is completely
@ -249,12 +249,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.WrapIf(err, "could not create temporary directory for install process")
return errors.WithMessage(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.WrapIf(err, "failed to write server installation script to disk before mount")
return errors.WithMessage(err, "failed to write server installation script to disk before mount")
}
defer f.Close()
@ -266,7 +266,7 @@ func (ip *InstallationProcess) writeScriptToDisk() error {
}
if err := scanner.Err(); err != nil {
return errors.WithStackIf(err)
return err
}
w.Flush()
@ -339,7 +339,7 @@ func (ip *InstallationProcess) pullInstallationImage() error {
}
if err := scanner.Err(); err != nil {
return errors.WithStackIf(err)
return err
}
return nil
@ -350,11 +350,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.WrapIf(err, "failed to write installation script to disk")
return errors.WithMessage(err, "failed to write installation script to disk")
}
if err := ip.pullInstallationImage(); err != nil {
return errors.WrapIf(err, "failed to pull updated installation container image for server")
return errors.WithMessage(err, "failed to pull updated installation container image for server")
}
opts := types.ContainerRemoveOptions{
@ -364,7 +364,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.WrapIf(err, "failed to remove existing install container for server")
return errors.WithMessage(err, "failed to remove existing install container for server")
}
}
@ -390,12 +390,12 @@ func (ip *InstallationProcess) AfterExecute(containerId string) error {
})
if err != nil && !client.IsErrNotFound(err) {
return errors.WithStackIf(err)
return err
}
f, err := os.OpenFile(ip.GetLogPath(), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return errors.WithStackIf(err)
return err
}
defer f.Close()
@ -424,15 +424,15 @@ func (ip *InstallationProcess) AfterExecute(containerId string) error {
| ------------------------------
`)
if err != nil {
return errors.WithStackIf(err)
return err
}
if err := tmpl.Execute(f, ip); err != nil {
return errors.WithStackIf(err)
return err
}
if _, err := io.Copy(f, reader); err != nil {
return errors.WithStackIf(err)
return err
}
return nil
@ -500,7 +500,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.WithStackIf(err)
return "", err
}
ip.Server.Log().WithField("container_id", r.ID).Info("running installation script for server in container")
@ -520,7 +520,7 @@ func (ip *InstallationProcess) Execute() (string, error) {
select {
case err := <-eChan:
if err != nil {
return "", errors.WithStackIf(err)
return "", err
}
case <-sChan:
}
@ -539,7 +539,7 @@ func (ip *InstallationProcess) StreamOutput(id string) error {
})
if err != nil {
return errors.WithStackIf(err)
return err
}
defer reader.Close()
@ -552,7 +552,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.WithStackIf(err),
"error": err,
}).Warn("error processing scanner line in installation output for server")
}
@ -567,7 +567,7 @@ func (s *Server) SyncInstallState(successful bool) error {
err := api.New().SendInstallationStatus(s.Id(), successful)
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStackIf(err)
return err
}
return errors.New(err.Error())

View File

@ -1,7 +1,6 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/apex/log"
"github.com/pterodactyl/wings/api"
@ -77,7 +76,7 @@ func (s *Server) StartEventListeners() {
s.Environment.SetState(environment.ProcessRunningState)
}
s.Log().WithField("error", errors.WithStackIf(err)).Error("failed to terminate environment after triggering throttle")
s.Log().WithField("error", err).Error("failed to terminate environment after triggering throttle")
}
}()
}
@ -106,7 +105,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.WithStackIf(err)).Warn("failed to unmarshal server environment stats")
s.Log().WithField("error", err).Warn("failed to unmarshal server environment stats")
return
}

View File

@ -1,12 +1,12 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"fmt"
"github.com/apex/log"
"github.com/creasty/defaults"
"github.com/gammazero/workerpool"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -35,7 +35,7 @@ func LoadDirectory() error {
configs, err := api.New().GetServers()
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStackIf(err)
return 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.WrapIf(err, "failed to set struct defaults for server configuration")
return nil, errors.WithMessage(err, "failed to set struct defaults for server configuration")
}
s := new(Server)
if err := defaults.Set(s); err != nil {
return nil, errors.WrapIf(err, "failed to set struct defaults for server")
return nil, errors.WithMessage(err, "failed to set struct defaults for server")
}
s.cfg = cfg

View File

@ -2,7 +2,7 @@ package server
import (
"context"
"emperror.dev/errors"
"github.com/pkg/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.WrapIf(err, "could not acquire lock on power state")
return errors.WithMessage(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.WrapIf(context.DeadlineExceeded, "could not acquire lock on power state")
return errors.WithMessage(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.WrapIf(err, "unable to sync server data from Panel instance")
return errors.WithMessage(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.WrapIf(err, "failed to chown root server directory during pre-boot process")
return errors.WithMessage(err, "failed to chown root server directory during pre-boot process")
}
}

View File

@ -2,9 +2,9 @@ package server
import (
"context"
"emperror.dev/errors"
"fmt"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -115,7 +115,7 @@ func (s *Server) Sync() error {
cfg, err := api.New().GetServerConfiguration(s.Id())
if err != nil {
if !api.IsRequestError(err) {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
return s.Environment.Create()

View File

@ -1,7 +1,6 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
@ -22,14 +21,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.WithStackIf(err)
return nil, 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.WithStackIf(err)
return nil, err
}
return states, nil
@ -46,7 +45,7 @@ func saveServerStates() error {
// Convert the map to a json object.
data, err := json.Marshal(states)
if err != nil {
return errors.WithStackIf(err)
return err
}
stateMutex.Lock()
@ -54,7 +53,7 @@ func saveServerStates() error {
// Write the data to the file
if err := ioutil.WriteFile(config.Get().System.GetStatesPath(), data, 0644); err != nil {
return errors.WithStackIf(err)
return err
}
return nil

View File

@ -1,10 +1,10 @@
package server
import (
"emperror.dev/errors"
"encoding/json"
"github.com/buger/jsonparser"
"github.com/imdario/mergo"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
)
@ -18,7 +18,7 @@ import (
func (s *Server) UpdateDataStructure(data []byte) error {
src := new(Configuration)
if err := json.Unmarshal(data, src); err != nil {
return errors.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return 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.WithStackIf(err)
return err
}
} else {
c.SkipEggScripts = v

View File

@ -1,7 +1,6 @@
package sftp
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/patrickmn/go-cache"
"github.com/pkg/sftp"
@ -58,14 +57,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.WithStackIf(err)).Error("error while processing file stat")
fs.logger.WithField("error", 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.WithStackIf(err)).Error("could not open file for reading")
fs.logger.WithField("source", p).WithField("error", err).Error("could not open file for reading")
return nil, sftp.ErrSshFxFailure
}
@ -108,7 +107,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.WithStackIf(err),
"error": err,
}).Error("error making path for file")
return nil, sftp.ErrSshFxFailure
@ -116,7 +115,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
file, err := os.Create(p)
if err != nil {
l.WithField("error", errors.WithStackIf(err)).Error("failed to create file")
l.WithField("error", err).Error("failed to create file")
return nil, sftp.ErrSshFxFailure
}
@ -124,7 +123,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.WithStackIf(err)).Warn("failed to set permissions on file")
l.WithField("error", err).Warn("failed to set permissions on file")
}
return file, nil
@ -133,7 +132,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.WithStackIf(statErr)).Error("encountered error performing file stat")
l.WithField("error", statErr).Error("encountered error performing file stat")
return nil, sftp.ErrSshFxFailure
}
@ -159,14 +158,14 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
return nil, sftp.ErrSSHFxNoSuchFile
}
l.WithField("flags", request.Flags).WithField("error", errors.WithStackIf(err)).Error("failed to open existing file on system")
l.WithField("flags", request.Flags).WithField("error", 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.WithStackIf(err)).Warn("error chowning file")
l.WithField("error", err).Warn("error chowning file")
}
return file, nil
@ -220,7 +219,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("error", errors.WithStackIf(err)).Error("failed to perform setstat on item")
l.WithField("error", err).Error("failed to perform setstat on item")
return sftp.ErrSSHFxFailure
}
return nil
@ -234,7 +233,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("target", target).WithField("error", errors.WithStackIf(err)).Error("failed to rename file")
l.WithField("target", target).WithField("error", err).Error("failed to rename file")
return sftp.ErrSshFxFailure
}
@ -246,7 +245,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.RemoveAll(p); err != nil {
l.WithField("error", errors.WithStackIf(err)).Error("failed to remove directory")
l.WithField("error", err).Error("failed to remove directory")
return sftp.ErrSshFxFailure
}
@ -258,7 +257,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.MkdirAll(p, 0755); err != nil {
l.WithField("error", errors.WithStackIf(err)).Error("failed to create directory")
l.WithField("error", err).Error("failed to create directory")
return sftp.ErrSshFxFailure
}
@ -270,7 +269,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
}
if err := os.Symlink(p, target); err != nil {
l.WithField("target", target).WithField("error", errors.WithStackIf(err)).Error("failed to create symlink")
l.WithField("target", target).WithField("error", err).Error("failed to create symlink")
return sftp.ErrSshFxFailure
}
@ -286,7 +285,7 @@ func (fs FileSystem) Filecmd(request *sftp.Request) error {
return sftp.ErrSSHFxNoSuchFile
}
l.WithField("error", errors.WithStackIf(err)).Error("failed to remove a file")
l.WithField("error", err).Error("failed to remove a file")
return sftp.ErrSshFxFailure
}
@ -305,7 +304,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.WithStackIf(err)).Warn("error chowning file")
l.WithField("error", err).Warn("error chowning file")
}
return sftp.ErrSshFxOk
@ -327,7 +326,7 @@ func (fs FileSystem) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
files, err := ioutil.ReadDir(p)
if err != nil {
fs.logger.WithField("error", errors.WithStackIf(err)).Error("error while listing directory")
fs.logger.WithField("error", err).Error("error while listing directory")
return nil, sftp.ErrSshFxFailure
}
@ -342,7 +341,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.WithStackIf(err)).Error("error performing stat on file")
fs.logger.WithField("source", p).WithField("error", err).Error("error performing stat on file")
return nil, sftp.ErrSshFxFailure
}

View File

@ -1,8 +1,8 @@
package sftp
import (
"emperror.dev/errors"
"github.com/apex/log"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/server"
@ -28,14 +28,14 @@ func Initialize(config config.SystemConfiguration) error {
}
if err := New(s); err != nil {
return errors.WithStackIf(err)
return 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.WithStackIf(err)).Error("failed to initialize SFTP subsystem")
log.WithField("subsystem", "sftp").WithField("error", err).Error("failed to initialize SFTP subsystem")
}
}(s)