Fix some typos and run gofmt on all .go files
This commit is contained in:
parent
b9f6e17a7d
commit
7ba32aca84
|
@ -59,9 +59,9 @@ func (r *PanelRequest) logDebug(req *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"method": req.Method,
|
"method": req.Method,
|
||||||
"endpoint": req.URL.String(),
|
"endpoint": req.URL.String(),
|
||||||
"headers": headers,
|
"headers": headers,
|
||||||
}).Debug("making request to external HTTP endpoint")
|
}).Debug("making request to external HTTP endpoint")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,13 +41,13 @@ var validUsernameRegexp = regexp.MustCompile(`^(?i)(.+)\.([a-z0-9]{8})$`)
|
||||||
|
|
||||||
func (r *PanelRequest) ValidateSftpCredentials(request SftpAuthRequest) (*SftpAuthResponse, error) {
|
func (r *PanelRequest) ValidateSftpCredentials(request SftpAuthRequest) (*SftpAuthResponse, error) {
|
||||||
// If the username doesn't meet the expected format that the Panel would even recognize just go ahead
|
// If the username doesn't meet the expected format that the Panel would even recognize just go ahead
|
||||||
// and bail out of the process here to avoid accidentially brute forcing the panel if a bot decides
|
// and bail out of the process here to avoid accidentally brute forcing the panel if a bot decides
|
||||||
// to connect to spam username attempts.
|
// to connect to spam username attempts.
|
||||||
if !validUsernameRegexp.MatchString(request.User) {
|
if !validUsernameRegexp.MatchString(request.User) {
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"subsystem": "sftp",
|
"subsystem": "sftp",
|
||||||
"username": request.User,
|
"username": request.User,
|
||||||
"ip": request.IP,
|
"ip": request.IP,
|
||||||
}).Warn("failed to validate user credentials (invalid format)")
|
}).Warn("failed to validate user credentials (invalid format)")
|
||||||
|
|
||||||
return nil, new(sftpInvalidCredentialsError)
|
return nil, new(sftpInvalidCredentialsError)
|
||||||
|
@ -84,4 +84,4 @@ func (r *PanelRequest) ValidateSftpCredentials(request SftpAuthRequest) (*SftpAu
|
||||||
}
|
}
|
||||||
|
|
||||||
return response, nil
|
return response, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,4 +57,4 @@ func RelocateConfiguration() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
return os.Chmod(config.DefaultLocation, 0600)
|
return os.Chmod(config.DefaultLocation, 0600)
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,7 @@ func diagnosticsCmdRun(cmd *cobra.Command, args []string) {
|
||||||
Name: "ReviewBeforeUpload",
|
Name: "ReviewBeforeUpload",
|
||||||
Prompt: &survey.Confirm{
|
Prompt: &survey.Confirm{
|
||||||
Message: "Do you want to review the collected data before uploading to hastebin.com?",
|
Message: "Do you want to review the collected data before uploading to hastebin.com?",
|
||||||
Help: "The data, especially the logs, might contain sensitive information, so you should review it. You will be asked again if you want to uplaod.",
|
Help: "The data, especially the logs, might contain sensitive information, so you should review it. You will be asked again if you want to upload.",
|
||||||
Default: true,
|
Default: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -82,7 +82,7 @@ func diagnosticsCmdRun(cmd *cobra.Command, args []string) {
|
||||||
_ = dockerInfo
|
_ = dockerInfo
|
||||||
|
|
||||||
output := &strings.Builder{}
|
output := &strings.Builder{}
|
||||||
fmt.Fprintln(output, "Pterodactly Wings - Diagnostics Report")
|
fmt.Fprintln(output, "Pterodactyl Wings - Diagnostics Report")
|
||||||
printHeader(output, "Versions")
|
printHeader(output, "Versions")
|
||||||
fmt.Fprintln(output, "wings:", system.Version)
|
fmt.Fprintln(output, "wings:", system.Version)
|
||||||
if dockerErr == nil {
|
if dockerErr == nil {
|
||||||
|
@ -210,7 +210,7 @@ func uploadToHastebin(hbUrl, content string) (string, error) {
|
||||||
u.Path = path.Join(u.Path, key)
|
u.Path = path.Join(u.Path, key)
|
||||||
return u.String(), nil
|
return u.String(), nil
|
||||||
}
|
}
|
||||||
return "", errors.New("Couldn't find key in response")
|
return "", errors.New("failed to find key in response")
|
||||||
}
|
}
|
||||||
|
|
||||||
func redact(s string) string {
|
func redact(s string) string {
|
||||||
|
|
|
@ -188,7 +188,7 @@ func NewFromPath(path string) (*Configuration, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sets the path where the configuration file is located on the server. This function should
|
// Sets the path where the configuration file is located on the server. This function should
|
||||||
// not be called except by processes that are generating the configuration such as the configration
|
// not be called except by processes that are generating the configuration such as the configuration
|
||||||
// command shipped with this software.
|
// command shipped with this software.
|
||||||
func (c *Configuration) unsafeSetPath(path string) {
|
func (c *Configuration) unsafeSetPath(path string) {
|
||||||
c.Lock()
|
c.Lock()
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (sc *SystemConfiguration) ConfigureDirectories() error {
|
||||||
|
|
||||||
// There are a non-trivial number of users out there whose data directories are actually a
|
// There are a non-trivial number of users out there whose data directories are actually a
|
||||||
// symlink to another location on the disk. If we do not resolve that final destination at this
|
// symlink to another location on the disk. If we do not resolve that final destination at this
|
||||||
// point things will appear to work, but endless errors whill be encountered when we try to
|
// point things will appear to work, but endless errors will be encountered when we try to
|
||||||
// verify accessed paths since they will all end up resolving outside the expected data directory.
|
// verify accessed paths since they will all end up resolving outside the expected data directory.
|
||||||
//
|
//
|
||||||
// For the sake of automating away as much of this as possible, see if the data directory is a
|
// For the sake of automating away as much of this as possible, see if the data directory is a
|
||||||
|
@ -98,7 +98,7 @@ func (sc *SystemConfiguration) ConfigureDirectories() error {
|
||||||
|
|
||||||
// Writes a logrotate file for wings to the system logrotate configuration directory if one
|
// Writes a logrotate file for wings to the system logrotate configuration directory if one
|
||||||
// exists and a logrotate file is not found. This allows us to basically automate away the log
|
// exists and a logrotate file is not found. This allows us to basically automate away the log
|
||||||
// rotatation for most installs, but also enable users to make modifications on their own.
|
// rotation for most installs, but also enable users to make modifications on their own.
|
||||||
func (sc *SystemConfiguration) EnableLogRotation() error {
|
func (sc *SystemConfiguration) EnableLogRotation() error {
|
||||||
// Do nothing if not enabled.
|
// Do nothing if not enabled.
|
||||||
if sc.EnableLogRotate == false {
|
if sc.EnableLogRotate == false {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
type ConsoleThrottles struct {
|
type ConsoleThrottles struct {
|
||||||
// Wether or not the throttler is enabled for this instance.
|
// Whether or not the throttler is enabled for this instance.
|
||||||
Enabled bool `json:"enabled" yaml:"enabled" default:"true"`
|
Enabled bool `json:"enabled" yaml:"enabled" default:"true"`
|
||||||
|
|
||||||
// The total number of throttle activations that must accumulate before a server is
|
// The total number of throttle activations that must accumulate before a server is
|
||||||
|
@ -20,4 +20,4 @@ type ConsoleThrottles struct {
|
||||||
// The amount of time that must pass between intervals before the count is reset. This
|
// The amount of time that must pass between intervals before the count is reset. This
|
||||||
// value is in milliseconds.
|
// value is in milliseconds.
|
||||||
CheckInterval uint64 `json:"check_interval" yaml:"check_interval" default:"100"`
|
CheckInterval uint64 `json:"check_interval" yaml:"check_interval" default:"100"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,4 +64,4 @@ func (a *Allocations) Exposed() nat.PortSet {
|
||||||
}
|
}
|
||||||
|
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ func (c *Configuration) Limits() Limits {
|
||||||
return c.settings.Limits
|
return c.settings.Limits
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rturns the allocations associated with this environment.
|
// Returns the allocations associated with this environment.
|
||||||
func (c *Configuration) Allocations() Allocations {
|
func (c *Configuration) Allocations() Allocations {
|
||||||
c.mu.RLock()
|
c.mu.RLock()
|
||||||
defer c.mu.RUnlock()
|
defer c.mu.RUnlock()
|
||||||
|
|
|
@ -17,4 +17,4 @@ func (c Console) Write(b []byte) (int, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,8 +57,8 @@ func (e *Environment) Attach() error {
|
||||||
e.SetStream(nil)
|
e.SetStream(nil)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Poll resources in a seperate thread since this will block the copy call below
|
// Poll resources in a separate thread since this will block the copy call below
|
||||||
// from being reached until it is completed if not run in a seperate process. However,
|
// from being reached until it is completed if not run in a separate process. However,
|
||||||
// we still want it to be stopped when the copy operation below is finished running which
|
// we still want it to be stopped when the copy operation below is finished running which
|
||||||
// indicates that the container is no longer running.
|
// indicates that the container is no longer running.
|
||||||
go func(ctx context.Context) {
|
go func(ctx context.Context) {
|
||||||
|
@ -167,13 +167,13 @@ func (e *Environment) Create() error {
|
||||||
PortBindings: a.Bindings(),
|
PortBindings: a.Bindings(),
|
||||||
|
|
||||||
// Configure the mounts for this container. First mount the server data directory
|
// Configure the mounts for this container. First mount the server data directory
|
||||||
// into the container as a r/w bine.
|
// into the container as a r/w bind.
|
||||||
Mounts: e.convertMounts(),
|
Mounts: e.convertMounts(),
|
||||||
|
|
||||||
// Configure the /tmp folder mapping in containers. This is necessary for some
|
// Configure the /tmp folder mapping in containers. This is necessary for some
|
||||||
// games that need to make use of it for downloads and other installation processes.
|
// games that need to make use of it for downloads and other installation processes.
|
||||||
Tmpfs: map[string]string{
|
Tmpfs: map[string]string{
|
||||||
"/tmp": "rw,exec,nosuid,size="+tmpfsSize+"M",
|
"/tmp": "rw,exec,nosuid,size=" + tmpfsSize + "M",
|
||||||
},
|
},
|
||||||
|
|
||||||
// Define resource limits for the container based on the data passed through
|
// Define resource limits for the container based on the data passed through
|
||||||
|
@ -228,7 +228,7 @@ func (e *Environment) convertMounts() []mount.Mount {
|
||||||
// Remove the Docker container from the machine. If the container is currently running
|
// Remove the Docker container from the machine. If the container is currently running
|
||||||
// it will be forcibly stopped by Docker.
|
// it will be forcibly stopped by Docker.
|
||||||
func (e *Environment) Destroy() error {
|
func (e *Environment) Destroy() error {
|
||||||
// We set it to stopping than offline to prevent crash detection from being triggeree.
|
// We set it to stopping than offline to prevent crash detection from being triggered.
|
||||||
e.setState(environment.ProcessStoppingState)
|
e.setState(environment.ProcessStoppingState)
|
||||||
|
|
||||||
err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{
|
err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{
|
||||||
|
@ -250,7 +250,7 @@ func (e *Environment) Destroy() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attaches to the log for the container. This avoids us missing cruicial output that
|
// Attaches to the log for the container. This avoids us missing crucial output that
|
||||||
// happens in the split seconds before the code moves from 'Starting' to 'Attaching'
|
// happens in the split seconds before the code moves from 'Starting' to 'Attaching'
|
||||||
// on the process.
|
// on the process.
|
||||||
func (e *Environment) followOutput() error {
|
func (e *Environment) followOutput() error {
|
||||||
|
@ -296,7 +296,7 @@ func (e *Environment) followOutput() error {
|
||||||
// cases an outage shouldn't affect users too badly. It'll at least keep existing servers working
|
// cases an outage shouldn't affect users too badly. It'll at least keep existing servers working
|
||||||
// correctly if anything.
|
// correctly if anything.
|
||||||
//
|
//
|
||||||
// TODO: handle authorization & local images
|
// TODO: local images
|
||||||
func (e *Environment) ensureImageExists(image string) error {
|
func (e *Environment) ensureImageExists(image string) error {
|
||||||
// Give it up to 15 minutes to pull the image. I think this should cover 99.8% of cases where an
|
// Give it up to 15 minutes to pull the image. I think this should cover 99.8% of cases where an
|
||||||
// image pull might fail. I can't imagine it will ever take more than 15 minutes to fully pull
|
// image pull might fail. I can't imagine it will ever take more than 15 minutes to fully pull
|
||||||
|
@ -362,7 +362,7 @@ func (e *Environment) ensureImageExists(image string) error {
|
||||||
log.WithField("image", image).Debug("pulling docker image... this could take a bit of time")
|
log.WithField("image", image).Debug("pulling docker image... this could take a bit of time")
|
||||||
|
|
||||||
// I'm not sure what the best approach here is, but this will block execution until the image
|
// I'm not sure what the best approach here is, but this will block execution until the image
|
||||||
// is done being pulled, which is what we neee.
|
// is done being pulled, which is what we need.
|
||||||
scanner := bufio.NewScanner(out)
|
scanner := bufio.NewScanner(out)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -13,8 +13,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Metadata struct {
|
type Metadata struct {
|
||||||
Image string
|
Image string
|
||||||
Stop *api.ProcessStopConfiguration
|
Stop *api.ProcessStopConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that the Docker environment is always implementing all of the methods
|
// Ensure that the Docker environment is always implementing all of the methods
|
||||||
|
@ -103,7 +103,7 @@ func (e *Environment) Events() *events.EventBus {
|
||||||
// Determines if the container exists in this environment. The ID passed through should be the
|
// Determines if the container exists in this environment. The ID passed through should be the
|
||||||
// server UUID since containers are created utilizing the server UUID as the name and docker
|
// server UUID since containers are created utilizing the server UUID as the name and docker
|
||||||
// will work fine when using the container name as the lookup parameter in addition to the longer
|
// will work fine when using the container name as the lookup parameter in addition to the longer
|
||||||
// ID auto-assigned when the container is createe.
|
// ID auto-assigned when the container is created.
|
||||||
func (e *Environment) Exists() (bool, error) {
|
func (e *Environment) Exists() (bool, error) {
|
||||||
_, err := e.client.ContainerInspect(context.Background(), e.Id)
|
_, err := e.client.ContainerInspect(context.Background(), e.Id)
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ func (e *Environment) IsRunning() (bool, error) {
|
||||||
return c.State.Running, nil
|
return c.State.Running, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine the container exit state and return the exit code and wether or not
|
// Determine the container exit state and return the exit code and whether or not
|
||||||
// the container was killed by the OOM killer.
|
// the container was killed by the OOM killer.
|
||||||
func (e *Environment) ExitState() (uint32, bool, error) {
|
func (e *Environment) ExitState() (uint32, bool, error) {
|
||||||
c, err := e.client.ContainerInspect(context.Background(), e.Id)
|
c, err := e.client.ContainerInspect(context.Background(), e.Id)
|
||||||
|
@ -148,7 +148,7 @@ func (e *Environment) ExitState() (uint32, bool, error) {
|
||||||
//
|
//
|
||||||
// However, someone reported an error in Discord about this scenario happening,
|
// However, someone reported an error in Discord about this scenario happening,
|
||||||
// so I guess this should prevent it? They didn't tell me how they caused it though
|
// so I guess this should prevent it? They didn't tell me how they caused it though
|
||||||
// so that's a mystery that will have to go unsolvee.
|
// so that's a mystery that will have to go unsolved.
|
||||||
//
|
//
|
||||||
// @see https://github.com/pterodactyl/panel/issues/2003
|
// @see https://github.com/pterodactyl/panel/issues/2003
|
||||||
if client.IsErrNotFound(err) {
|
if client.IsErrNotFound(err) {
|
||||||
|
@ -175,4 +175,4 @@ func (e *Environment) SetStopConfiguration(c *api.ProcessStopConfiguration) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
e.meta.Stop = c
|
e.meta.Stop = c
|
||||||
e.mu.Unlock()
|
e.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ func (e *Environment) OnBeforeStart() error {
|
||||||
// container and data storage directory.
|
// container and data storage directory.
|
||||||
//
|
//
|
||||||
// This won't actually run an installation process however, it is just here to ensure the
|
// This won't actually run an installation process however, it is just here to ensure the
|
||||||
// environment gets created properly if it is missing and the server is startee. We're making
|
// environment gets created properly if it is missing and the server is started. We're making
|
||||||
// an assumption that all of the files will still exist at this point.
|
// an assumption that all of the files will still exist at this point.
|
||||||
if err := e.Create(); err != nil {
|
if err := e.Create(); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -64,7 +64,7 @@ func (e *Environment) Start() error {
|
||||||
|
|
||||||
if c, err := e.client.ContainerInspect(context.Background(), e.Id); err != nil {
|
if c, err := e.client.ContainerInspect(context.Background(), e.Id); err != nil {
|
||||||
// Do nothing if the container is not found, we just don't want to continue
|
// Do nothing if the container is not found, we just don't want to continue
|
||||||
// to the next block of code here. This check was inlined here to guard againt
|
// to the next block of code here. This check was inlined here to guard against
|
||||||
// a nil-pointer when checking c.State below.
|
// a nil-pointer when checking c.State below.
|
||||||
//
|
//
|
||||||
// @see https://github.com/pterodactyl/panel/issues/2000
|
// @see https://github.com/pterodactyl/panel/issues/2000
|
||||||
|
@ -128,7 +128,7 @@ func (e *Environment) Stop() error {
|
||||||
|
|
||||||
if s == nil || s.Type == api.ProcessStopSignal {
|
if s == nil || s.Type == api.ProcessStopSignal {
|
||||||
if s == nil {
|
if s == nil {
|
||||||
log.WithField("container_id", e.Id).Warn("no stop configuration detected for environment, using termination proceedure")
|
log.WithField("container_id", e.Id).Warn("no stop configuration detected for environment, using termination procedure")
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.Terminate(os.Kill)
|
return e.Terminate(os.Kill)
|
||||||
|
@ -217,7 +217,7 @@ func (e *Environment) Terminate(signal os.Signal) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We set it to stopping than offline to prevent crash detection from being triggeree.
|
// We set it to stopping than offline to prevent crash detection from being triggered.
|
||||||
e.setState(environment.ProcessStoppingState)
|
e.setState(environment.ProcessStoppingState)
|
||||||
|
|
||||||
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
|
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
|
||||||
|
|
|
@ -27,7 +27,7 @@ func (e *Environment) setState(state string) error {
|
||||||
// Get the current state of the environment before changing it.
|
// Get the current state of the environment before changing it.
|
||||||
prevState := e.State()
|
prevState := e.State()
|
||||||
|
|
||||||
// Emit the event to any listeners that are currently registeree.
|
// Emit the event to any listeners that are currently registered.
|
||||||
if prevState != state {
|
if prevState != state {
|
||||||
// If the state changed make sure we update the internal tracking to note that.
|
// If the state changed make sure we update the internal tracking to note that.
|
||||||
e.stMu.Lock()
|
e.stMu.Lock()
|
||||||
|
|
|
@ -22,7 +22,7 @@ type Mount struct {
|
||||||
// that we're mounting into the container at the Target location.
|
// that we're mounting into the container at the Target location.
|
||||||
Source string `json:"source"`
|
Source string `json:"source"`
|
||||||
|
|
||||||
// Wether or not the directory is being mounted as read-only. It is up to the environment to
|
// Whether or not the directory is being mounted as read-only. It is up to the environment to
|
||||||
// handle this value correctly and ensure security expectations are met with its usage.
|
// handle this value correctly and ensure security expectations are met with its usage.
|
||||||
ReadOnly bool `json:"read_only"`
|
ReadOnly bool `json:"read_only"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -359,7 +359,7 @@ func (f *ConfigurationFile) parseYamlFile(path string) error {
|
||||||
|
|
||||||
// Unmarshal the yaml data into a JSON interface such that we can work with
|
// Unmarshal the yaml data into a JSON interface such that we can work with
|
||||||
// any arbitrary data structure. If we don't do this, I can't use gabs which
|
// any arbitrary data structure. If we don't do this, I can't use gabs which
|
||||||
// makes working with unknown JSON signficiantly easier.
|
// makes working with unknown JSON significantly easier.
|
||||||
jsonBytes, err := json.Marshal(dyno.ConvertMapI2MapS(i))
|
jsonBytes, err := json.Marshal(dyno.ConvertMapI2MapS(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -21,4 +21,4 @@ func (cv *ReplaceValue) String() string {
|
||||||
|
|
||||||
func (cv *ReplaceValue) Type() jsonparser.ValueType {
|
func (cv *ReplaceValue) Type() jsonparser.ValueType {
|
||||||
return cv.valueType
|
return cv.valueType
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,4 +95,4 @@ func getDownloadFile(c *gin.Context) {
|
||||||
c.Header("Content-Type", "application/octet-stream")
|
c.Header("Content-Type", "application/octet-stream")
|
||||||
|
|
||||||
bufio.NewReader(f).WriteTo(c.Writer)
|
bufio.NewReader(f).WriteTo(c.Writer)
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ func postServerPower(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass the actual heavy processing off to a seperate thread to handle so that
|
// Pass the actual heavy processing off to a separate thread to handle so that
|
||||||
// we can immediately return a response from the server. Some of these actions
|
// we can immediately return a response from the server. Some of these actions
|
||||||
// can take quite some time, especially stopping or restarting.
|
// can take quite some time, especially stopping or restarting.
|
||||||
go func(s *server.Server) {
|
go func(s *server.Server) {
|
||||||
|
@ -176,7 +176,7 @@ func postServerReinstall(c *gin.Context) {
|
||||||
c.Status(http.StatusAccepted)
|
c.Status(http.StatusAccepted)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deletes a server from the wings daemon and deassociates its objects.
|
// Deletes a server from the wings daemon and dissociate it's objects.
|
||||||
func deleteServer(c *gin.Context) {
|
func deleteServer(c *gin.Context) {
|
||||||
s := GetServer(c.Param("server"))
|
s := GetServer(c.Param("server"))
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ func postCreateServer(c *gin.Context) {
|
||||||
func postUpdateConfiguration(c *gin.Context) {
|
func postUpdateConfiguration(c *gin.Context) {
|
||||||
// A backup of the configuration for error purposes.
|
// A backup of the configuration for error purposes.
|
||||||
ccopy := *config.Get()
|
ccopy := *config.Get()
|
||||||
// A copy of the configuration we're using to bind the data recevied into.
|
// A copy of the configuration we're using to bind the data received into.
|
||||||
cfg := *config.Get()
|
cfg := *config.Get()
|
||||||
|
|
||||||
// BindJSON sends 400 if the request fails, all we need to do is return
|
// BindJSON sends 400 if the request fails, all we need to do is return
|
||||||
|
|
|
@ -147,11 +147,11 @@ func postTransfer(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.WithField("error", errors.WithStack(rerr)).Error("recieved error response from panel while notifying of transfer failure")
|
l.WithField("error", errors.WithStack(rerr)).Error("received error response from panel while notifying of transfer failure")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
l.Debug("notified panel of tranfer failure")
|
l.Debug("notified panel of transfer failure")
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// Make a new GET request to the URL the panel gave us.
|
// Make a new GET request to the URL the panel gave us.
|
||||||
|
|
|
@ -16,7 +16,7 @@ type Message struct {
|
||||||
//
|
//
|
||||||
// - status : Returns the server's power state.
|
// - status : Returns the server's power state.
|
||||||
// - logs : Returns the server log data at the time of the request.
|
// - logs : Returns the server log data at the time of the request.
|
||||||
// - power : Performs a power action aganist the server based the data.
|
// - power : Performs a power action against the server based the data.
|
||||||
// - command : Performs a command on a server using the data field.
|
// - command : Performs a command on a server using the data field.
|
||||||
Event string `json:"event"`
|
Event string `json:"event"`
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ func (a *Archive) Create(dst string, ctx context.Context) (os.FileInfo, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
gzw, _ := gzip.NewWriterLevel(f, gzip.BestSpeed)
|
gzw, _ := gzip.NewWriterLevel(f, gzip.BestSpeed)
|
||||||
_ = gzw.SetConcurrency(1 << 20, maxCpu)
|
_ = gzw.SetConcurrency(1<<20, maxCpu)
|
||||||
|
|
||||||
defer gzw.Flush()
|
defer gzw.Flush()
|
||||||
defer gzw.Close()
|
defer gzw.Close()
|
||||||
|
|
|
@ -77,10 +77,10 @@ func (s *S3Backup) generateRemoteRequest(rc io.ReadCloser) (*http.Response, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Body = rc
|
r.Body = rc
|
||||||
|
|
||||||
log.WithFields(log.Fields{
|
log.WithFields(log.Fields{
|
||||||
"endpoint": s.PresignedUrl,
|
"endpoint": s.PresignedUrl,
|
||||||
"headers": r.Header,
|
"headers": r.Header,
|
||||||
}).Debug("uploading backup to remote S3 endpoint")
|
}).Debug("uploading backup to remote S3 endpoint")
|
||||||
|
|
||||||
return http.DefaultClient.Do(r)
|
return http.DefaultClient.Do(r)
|
||||||
|
|
|
@ -29,4 +29,4 @@ func (s *Server) UpdateConfigurationFiles() {
|
||||||
}
|
}
|
||||||
|
|
||||||
pool.StopWait()
|
pool.StopWait()
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,6 @@ func (s *Server) Throttler() *ConsoleThrottler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sends output to the server console formatted to appear correctly as being sent
|
// Sends output to the server console formatted to appear correctly as being sent
|
||||||
// from Wings.
|
// from Wings.
|
||||||
func (s *Server) PublishConsoleOutputFromDaemon(data string) {
|
func (s *Server) PublishConsoleOutputFromDaemon(data string) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ func (cd *CrashHandler) SetLastCrash(t time.Time) {
|
||||||
// if it was the result of an event that we should try to recover from.
|
// if it was the result of an event that we should try to recover from.
|
||||||
//
|
//
|
||||||
// This function assumes it is called under circumstances where a crash is suspected
|
// This function assumes it is called under circumstances where a crash is suspected
|
||||||
// of occuring. It will not do anything to determine if it was actually a crash, just
|
// of occurring. It will not do anything to determine if it was actually a crash, just
|
||||||
// look at the exit state and check if it meets the criteria of being called a crash
|
// look at the exit state and check if it meets the criteria of being called a crash
|
||||||
// by Wings.
|
// by Wings.
|
||||||
//
|
//
|
||||||
|
@ -75,7 +75,7 @@ func (s *Server) handleServerCrash() error {
|
||||||
c := s.crasher.LastCrashTime()
|
c := s.crasher.LastCrashTime()
|
||||||
// If the last crash time was within the last 60 seconds we do not want to perform
|
// If the last crash time was within the last 60 seconds we do not want to perform
|
||||||
// an automatic reboot of the process. Return an error that can be handled.
|
// an automatic reboot of the process. Return an error that can be handled.
|
||||||
if !c.IsZero() && c.Add(time.Second * 60).After(time.Now()) {
|
if !c.IsZero() && c.Add(time.Second*60).After(time.Now()) {
|
||||||
s.PublishConsoleOutputFromDaemon("Aborting automatic reboot: last crash occurred less than 60 seconds ago.")
|
s.PublishConsoleOutputFromDaemon("Aborting automatic reboot: last crash occurred less than 60 seconds ago.")
|
||||||
|
|
||||||
return &crashTooFrequent{}
|
return &crashTooFrequent{}
|
||||||
|
@ -84,4 +84,4 @@ func (s *Server) handleServerCrash() error {
|
||||||
s.crasher.SetLastCrash(time.Now())
|
s.crasher.SetLastCrash(time.Now())
|
||||||
|
|
||||||
return s.HandlePowerAction(PowerActionStart)
|
return s.HandlePowerAction(PowerActionStart)
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,4 +37,4 @@ func IsServerDoesNotExistError(err error) bool {
|
||||||
_, ok := err.(*serverDoesNotExist)
|
_, ok := err.(*serverDoesNotExist)
|
||||||
|
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,14 +183,14 @@ func (fs *Filesystem) ParallelSafePath(paths []string) ([]string, error) {
|
||||||
pi := p
|
pi := p
|
||||||
|
|
||||||
// Recursively call this function to continue digging through the directory tree within
|
// Recursively call this function to continue digging through the directory tree within
|
||||||
// a seperate goroutine. If the context is canceled abort this process.
|
// a separate goroutine. If the context is canceled abort this process.
|
||||||
g.Go(func() error {
|
g.Go(func() error {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
default:
|
default:
|
||||||
// If the callback returns true, go ahead and keep walking deeper. This allows
|
// If the callback returns true, go ahead and keep walking deeper. This allows
|
||||||
// us to programatically continue deeper into directories, or stop digging
|
// us to programmatically continue deeper into directories, or stop digging
|
||||||
// if that pathway knows it needs nothing else.
|
// if that pathway knows it needs nothing else.
|
||||||
if c, err := fs.SafePath(pi); err != nil {
|
if c, err := fs.SafePath(pi); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -647,7 +647,7 @@ func (fs *Filesystem) Copy(p string) error {
|
||||||
// Deletes a file or folder from the system. Prevents the user from accidentally
|
// Deletes a file or folder from the system. Prevents the user from accidentally
|
||||||
// (or maliciously) removing their root server data directory.
|
// (or maliciously) removing their root server data directory.
|
||||||
func (fs *Filesystem) Delete(p string) error {
|
func (fs *Filesystem) Delete(p string) error {
|
||||||
// This is one of the few (only?) places in the codebase where we're explictly not using
|
// This is one of the few (only?) places in the codebase where we're explicitly not using
|
||||||
// the SafePath functionality when working with user provided input. If we did, you would
|
// the SafePath functionality when working with user provided input. If we did, you would
|
||||||
// not be able to delete a file that is a symlink pointing to a location outside of the data
|
// not be able to delete a file that is a symlink pointing to a location outside of the data
|
||||||
// directory.
|
// directory.
|
||||||
|
|
|
@ -9,5 +9,5 @@ import (
|
||||||
func (s *Stat) CTime() time.Time {
|
func (s *Stat) CTime() time.Time {
|
||||||
st := s.Info.Sys().(*syscall.Stat_t)
|
st := s.Info.Sys().(*syscall.Stat_t)
|
||||||
|
|
||||||
return time.Unix(int64(st.Ctimespec.Sec), int64(st.Ctimespec.Nsec))
|
return time.Unix(st.Ctimespec.Sec, st.Ctimespec.Nsec)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,5 @@ import (
|
||||||
func (s *Stat) CTime() time.Time {
|
func (s *Stat) CTime() time.Time {
|
||||||
st := s.Info.Sys().(*syscall.Stat_t)
|
st := s.Info.Sys().(*syscall.Stat_t)
|
||||||
|
|
||||||
return time.Unix(int64(st.Ctim.Sec), int64(st.Ctim.Nsec))
|
return time.Unix(st.Ctim.Sec, st.Ctim.Nsec)
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,4 +9,4 @@ import (
|
||||||
// for right now.
|
// for right now.
|
||||||
func (s *Stat) CTime() time.Time {
|
func (s *Stat) CTime() time.Time {
|
||||||
return s.Info.ModTime()
|
return s.Info.ModTime()
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ import (
|
||||||
// Executes the installation stack for a server process. Bubbles any errors up to the calling
|
// Executes the installation stack for a server process. Bubbles any errors up to the calling
|
||||||
// function which should handle contacting the panel to notify it of the server state.
|
// function which should handle contacting the panel to notify it of the server state.
|
||||||
//
|
//
|
||||||
// Pass true as the first arugment in order to execute a server sync before the process to
|
// Pass true as the first argument in order to execute a server sync before the process to
|
||||||
// ensure the latest information is used.
|
// ensure the latest information is used.
|
||||||
func (s *Server) Install(sync bool) error {
|
func (s *Server) Install(sync bool) error {
|
||||||
if sync {
|
if sync {
|
||||||
|
@ -197,7 +197,7 @@ func (ip *InstallationProcess) RemoveContainer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs the installation process, this is done as a backgrounded thread. This will configure
|
// Runs the installation process, this is done as in a background thread. This will configure
|
||||||
// the required environment, and then spin up the installation container.
|
// the required environment, and then spin up the installation container.
|
||||||
//
|
//
|
||||||
// Once the container finishes installing the results will be stored in an installation
|
// Once the container finishes installing the results will be stored in an installation
|
||||||
|
@ -210,7 +210,7 @@ func (ip *InstallationProcess) Run() error {
|
||||||
|
|
||||||
// We now have an exclusive lock on this installation process. Ensure that whenever this
|
// We now have an exclusive lock on this installation process. Ensure that whenever this
|
||||||
// process is finished that the semaphore is released so that other processes and be executed
|
// process is finished that the semaphore is released so that other processes and be executed
|
||||||
// without encounting a wait timeout.
|
// without encountering a wait timeout.
|
||||||
defer func() {
|
defer func() {
|
||||||
ip.Server.Log().Debug("releasing installation process lock")
|
ip.Server.Log().Debug("releasing installation process lock")
|
||||||
ip.Server.installer.sem.Release(1)
|
ip.Server.installer.sem.Release(1)
|
||||||
|
@ -464,13 +464,13 @@ func (ip *InstallationProcess) Execute() (string, error) {
|
||||||
ip.Server.Events().Publish(DaemonMessageEvent, "Installation process completed.")
|
ip.Server.Events().Publish(DaemonMessageEvent, "Installation process completed.")
|
||||||
}(r.ID)
|
}(r.ID)
|
||||||
|
|
||||||
sChann, eChann := ip.client.ContainerWait(ip.context, r.ID, container.WaitConditionNotRunning)
|
sChan, eChan := ip.client.ContainerWait(ip.context, r.ID, container.WaitConditionNotRunning)
|
||||||
select {
|
select {
|
||||||
case err := <-eChann:
|
case err := <-eChan:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errors.WithStack(err)
|
return "", errors.WithStack(err)
|
||||||
}
|
}
|
||||||
case <-sChann:
|
case <-sChan:
|
||||||
}
|
}
|
||||||
|
|
||||||
return r.ID, nil
|
return r.ID, nil
|
||||||
|
|
|
@ -33,8 +33,10 @@ func (s *Server) StartEventListeners() {
|
||||||
|
|
||||||
// Also pass the data along to the console output channel.
|
// Also pass the data along to the console output channel.
|
||||||
s.onConsoleOutput(data.Data)
|
s.onConsoleOutput(data.Data)
|
||||||
|
|
||||||
case data := <-state:
|
case data := <-state:
|
||||||
s.SetState(data.Data)
|
s.SetState(data.Data)
|
||||||
|
|
||||||
case data := <-stats:
|
case data := <-stats:
|
||||||
st := new(environment.Stats)
|
st := new(environment.Stats)
|
||||||
if err := json.Unmarshal([]byte(data.Data), st); err != nil {
|
if err := json.Unmarshal([]byte(data.Data), st); err != nil {
|
||||||
|
|
|
@ -94,7 +94,7 @@ func (s *Server) HandlePowerAction(action PowerAction, waitSeconds ...int) error
|
||||||
|
|
||||||
return s.Environment.Start()
|
return s.Environment.Start()
|
||||||
case PowerActionStop:
|
case PowerActionStop:
|
||||||
// We're specificially waiting for the process to be stopped here, otherwise the lock is released
|
// We're specifically waiting for the process to be stopped here, otherwise the lock is released
|
||||||
// too soon, and you can rack up all sorts of issues.
|
// too soon, and you can rack up all sorts of issues.
|
||||||
return s.Environment.WaitForStop(10*60, true)
|
return s.Environment.WaitForStop(10*60, true)
|
||||||
case PowerActionRestart:
|
case PowerActionRestart:
|
||||||
|
@ -148,7 +148,7 @@ func (s *Server) onBeforeStart() error {
|
||||||
|
|
||||||
// Update the configuration files defined for the server before beginning the boot process.
|
// Update the configuration files defined for the server before beginning the boot process.
|
||||||
// This process executes a bunch of parallel updates, so we just block until that process
|
// This process executes a bunch of parallel updates, so we just block until that process
|
||||||
// is completee. Any errors as a result of this will just be bubbled out in the logger,
|
// is complete. Any errors as a result of this will just be bubbled out in the logger,
|
||||||
// we don't need to actively do anything about it at this point, worst comes to worst the
|
// we don't need to actively do anything about it at this point, worst comes to worst the
|
||||||
// server starts in a weird state and the user can manually adjust.
|
// server starts in a weird state and the user can manually adjust.
|
||||||
s.PublishConsoleOutputFromDaemon("Updating process configuration files...")
|
s.PublishConsoleOutputFromDaemon("Updating process configuration files...")
|
||||||
|
|
|
@ -39,8 +39,12 @@ func (s *Server) emitProcUsage() {
|
||||||
s.resources.mu.RLock()
|
s.resources.mu.RLock()
|
||||||
defer s.resources.mu.RUnlock()
|
defer s.resources.mu.RUnlock()
|
||||||
|
|
||||||
b, _ := json.Marshal(s.resources)
|
b, err := json.Marshal(s.resources)
|
||||||
s.Events().Publish(StatsEvent, string(b))
|
if err == nil {
|
||||||
|
s.Events().Publish(StatsEvent, string(b))
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: This might be a good place to add a debug log if stats are not sending.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the servers current state.
|
// Returns the servers current state.
|
||||||
|
|
|
@ -156,7 +156,7 @@ func (s *Server) IsBootable() bool {
|
||||||
return exists
|
return exists
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initalizes a server instance. This will run through and ensure that the environment
|
// Initializes a server instance. This will run through and ensure that the environment
|
||||||
// for the server is setup, and that all of the necessary files are created.
|
// for the server is setup, and that all of the necessary files are created.
|
||||||
func (s *Server) CreateEnvironment() error {
|
func (s *Server) CreateEnvironment() error {
|
||||||
// Ensure the data directory exists before getting too far through this process.
|
// Ensure the data directory exists before getting too far through this process.
|
||||||
|
|
|
@ -145,7 +145,7 @@ func (s *Server) SyncWithEnvironment() {
|
||||||
// will be gracefully stopped (and terminated if it refuses to stop).
|
// will be gracefully stopped (and terminated if it refuses to stop).
|
||||||
s.Log().Info("server suspended with running process state, terminating now")
|
s.Log().Info("server suspended with running process state, terminating now")
|
||||||
|
|
||||||
go func (s *Server) {
|
go func(s *Server) {
|
||||||
if err := s.Environment.WaitForStop(60, true); err != nil {
|
if err := s.Environment.WaitForStop(60, true); err != nil {
|
||||||
s.Log().WithField("error", err).Warn("failed to terminate server environment after suspension")
|
s.Log().WithField("error", err).Warn("failed to terminate server environment after suspension")
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,4 +16,4 @@ func (e fxerr) Error() string {
|
||||||
default:
|
default:
|
||||||
return "Failure"
|
return "Failure"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ type FileSystem struct {
|
||||||
UUID string
|
UUID string
|
||||||
Permissions []string
|
Permissions []string
|
||||||
ReadOnly bool
|
ReadOnly bool
|
||||||
User SftpUser
|
User User
|
||||||
Cache *cache.Cache
|
Cache *cache.Cache
|
||||||
|
|
||||||
PathValidator func(fs FileSystem, p string) (string, error)
|
PathValidator func(fs FileSystem, p string) (string, error)
|
||||||
|
@ -107,7 +107,7 @@ func (fs FileSystem) Filewrite(request *sftp.Request) (io.WriterAt, error) {
|
||||||
// Create all of the directories leading up to the location where this file is being created.
|
// Create all of the directories leading up to the location where this file is being created.
|
||||||
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(p), 0755); err != nil {
|
||||||
l.WithFields(log.Fields{
|
l.WithFields(log.Fields{
|
||||||
"path": filepath.Dir(p),
|
"path": filepath.Dir(p),
|
||||||
"error": errors.WithStack(err),
|
"error": errors.WithStack(err),
|
||||||
}).Error("error making path for file")
|
}).Error("error making path for file")
|
||||||
|
|
||||||
|
@ -351,7 +351,7 @@ func (fs FileSystem) Filelist(request *sftp.Request) (sftp.ListerAt, error) {
|
||||||
default:
|
default:
|
||||||
// Before adding readlink support we need to evaluate any potential security risks
|
// Before adding readlink support we need to evaluate any potential security risks
|
||||||
// as a result of navigating around to a location that is outside the home directory
|
// as a result of navigating around to a location that is outside the home directory
|
||||||
// for the logged in user. I don't forsee it being much of a problem, but I do want to
|
// for the logged in user. I don't foresee it being much of a problem, but I do want to
|
||||||
// check it out before slapping some code here. Until then, we'll just return an
|
// check it out before slapping some code here. Until then, we'll just return an
|
||||||
// unsupported response code.
|
// unsupported response code.
|
||||||
return nil, sftp.ErrSshFxOpUnsupported
|
return nil, sftp.ErrSshFxOpUnsupported
|
||||||
|
|
|
@ -27,7 +27,7 @@ type Settings struct {
|
||||||
BindAddress string
|
BindAddress string
|
||||||
}
|
}
|
||||||
|
|
||||||
type SftpUser struct {
|
type User struct {
|
||||||
Uid int
|
Uid int
|
||||||
Gid int
|
Gid int
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ type Server struct {
|
||||||
cache *cache.Cache
|
cache *cache.Cache
|
||||||
|
|
||||||
Settings Settings
|
Settings Settings
|
||||||
User SftpUser
|
User User
|
||||||
|
|
||||||
PathValidator func(fs FileSystem, p string) (string, error)
|
PathValidator func(fs FileSystem, p string) (string, error)
|
||||||
DiskSpaceValidator func(fs FileSystem) bool
|
DiskSpaceValidator func(fs FileSystem) bool
|
||||||
|
|
|
@ -12,7 +12,7 @@ var noMatchingServerError = errors.New("no matching server with that UUID was fo
|
||||||
|
|
||||||
func Initialize(config config.SystemConfiguration) error {
|
func Initialize(config config.SystemConfiguration) error {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
User: SftpUser{
|
User: User{
|
||||||
Uid: config.User.Uid,
|
Uid: config.User.Uid,
|
||||||
Gid: config.User.Gid,
|
Gid: config.User.Gid,
|
||||||
},
|
},
|
||||||
|
@ -66,7 +66,7 @@ func validateDiskSpace(fs FileSystem) bool {
|
||||||
return s.Filesystem.HasSpaceAvailable(true)
|
return s.Filesystem.HasSpaceAvailable(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validates a set of credentials for a SFTP login aganist Pterodactyl Panel and returns
|
// Validates a set of credentials for a SFTP login against Pterodactyl Panel and returns
|
||||||
// the server's UUID if the credentials were valid.
|
// the server's UUID if the credentials were valid.
|
||||||
func validateCredentials(c api.SftpAuthRequest) (*api.SftpAuthResponse, error) {
|
func validateCredentials(c api.SftpAuthRequest) (*api.SftpAuthResponse, error) {
|
||||||
f := log.Fields{"subsystem": "sftp", "username": c.User, "ip": c.IP}
|
f := log.Fields{"subsystem": "sftp", "username": c.User, "ip": c.IP}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user