Merge branch 'develop' into pr/64

This commit is contained in:
Dane Everitt 2020-10-11 15:25:07 -07:00
commit 3463c223e8
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
4 changed files with 53 additions and 27 deletions

View File

@ -13,6 +13,7 @@ import (
"path" "path"
"strconv" "strconv"
"strings" "strings"
"time"
"github.com/AlecAivazis/survey/v2" "github.com/AlecAivazis/survey/v2"
"github.com/AlecAivazis/survey/v2/terminal" "github.com/AlecAivazis/survey/v2/terminal"
@ -25,8 +26,8 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
const DefaultHastebinUrl = "https://hastebin.com" const DefaultHastebinUrl = "https://ptero.co"
const DefaultLogLines = 50 const DefaultLogLines = 200
var ( var (
diagnosticsArgs struct { diagnosticsArgs struct {
@ -103,22 +104,24 @@ func diagnosticsCmdRun(cmd *cobra.Command, args []string) {
cfg, err := config.ReadConfiguration(config.DefaultLocation) cfg, err := config.ReadConfiguration(config.DefaultLocation)
if cfg != nil { if cfg != nil {
fmt.Fprintln(output, " Panel Location:", redact(cfg.PanelLocation)) fmt.Fprintln(output, " Panel Location:", redact(cfg.PanelLocation))
fmt.Fprintln(output, "Api Host:", redact(cfg.Api.Host)) fmt.Fprintln(output, "")
fmt.Fprintln(output, "Api Port:", cfg.Api.Port) fmt.Fprintln(output, "Internal Webserver:", redact(cfg.Api.Host) + ":", cfg.Api.Port)
fmt.Fprintln(output, "Api Ssl Enabled:", cfg.Api.Ssl.Enabled) fmt.Fprintln(output, " SSL Enabled:", cfg.Api.Ssl.Enabled)
fmt.Fprintln(output, "Api Ssl Certificate:", redact(cfg.Api.Ssl.CertificateFile)) fmt.Fprintln(output, " SSL Certificate:", redact(cfg.Api.Ssl.CertificateFile))
fmt.Fprintln(output, "Api Ssl Key:", redact(cfg.Api.Ssl.KeyFile)) fmt.Fprintln(output, " SSL Key:", redact(cfg.Api.Ssl.KeyFile))
fmt.Fprintln(output, "Sftp Address:", redact(cfg.System.Sftp.Address)) fmt.Fprintln(output, "")
fmt.Fprintln(output, "Sftp Port:", cfg.System.Sftp.Port) fmt.Fprintln(output, " SFTP Server:", redact(cfg.System.Sftp.Address), ":", cfg.System.Sftp.Port)
fmt.Fprintln(output, "Sftp Read Only:", cfg.System.Sftp.ReadOnly) fmt.Fprintln(output, " SFTP Read-Only:", cfg.System.Sftp.ReadOnly)
fmt.Fprintln(output, "Sftp Diskchecking Disabled:", cfg.System.Sftp.DisableDiskChecking) fmt.Fprintln(output, "")
fmt.Fprintln(output, "System Root Directory:", cfg.System.RootDirectory) fmt.Fprintln(output, " Root Directory:", cfg.System.RootDirectory)
fmt.Fprintln(output, "System Logs Directory:", cfg.System.LogDirectory) fmt.Fprintln(output, " Logs Directory:", cfg.System.LogDirectory)
fmt.Fprintln(output, "System Data Directory:", cfg.System.Data) fmt.Fprintln(output, " Data Directory:", cfg.System.Data)
fmt.Fprintln(output, "System Archive Directory:", cfg.System.ArchiveDirectory) fmt.Fprintln(output, " Archive Directory:", cfg.System.ArchiveDirectory)
fmt.Fprintln(output, "System Backup Directory:", cfg.System.BackupDirectory) fmt.Fprintln(output, " Backup Directory:", cfg.System.BackupDirectory)
fmt.Fprintln(output, "System Username:", cfg.System.Username) fmt.Fprintln(output, "")
fmt.Fprintln(output, "Debug Enabled:", cfg.Debug) fmt.Fprintln(output, " Username:", cfg.System.Username)
fmt.Fprintln(output, " Server Time:", time.Now().Format(time.RFC1123Z))
fmt.Fprintln(output, " Debug Mode:", cfg.Debug)
} else { } else {
fmt.Println("Failed to load configuration.", err) fmt.Println("Failed to load configuration.", err)
} }

View File

@ -73,9 +73,6 @@ type Configuration struct {
// Defines the configuration of the internal SFTP server. // Defines the configuration of the internal SFTP server.
type SftpConfiguration struct { type SftpConfiguration struct {
// If set to true disk checking will not be performed. This will prevent the SFTP
// server from checking the total size of a directory when uploading files.
DisableDiskChecking bool `default:"false" yaml:"disable_disk_checking"`
// The bind address of the SFTP server. // The bind address of the SFTP server.
Address string `default:"0.0.0.0" json:"bind_address" yaml:"bind_address"` Address string `default:"0.0.0.0" json:"bind_address" yaml:"bind_address"`
// The bind port of the SFTP server. // The bind port of the SFTP server.

View File

@ -75,6 +75,16 @@ func (fs *Filesystem) HasSpaceAvailable(allowStaleValue bool) bool {
return size <= fs.MaxDisk() return size <= fs.MaxDisk()
} }
// Returns the cached value for the amount of disk space used by the filesystem. Do not rely on this
// function for critical logical checks. It should only be used in areas where the actual disk usage
// does not need to be perfect, e.g. API responses for server resource usage.
func (fs *Filesystem) CachedUsage() int64 {
fs.mu.RLock()
defer fs.mu.RUnlock()
return fs.diskUsed
}
// Internal helper function to allow other parts of the codebase to check the total used disk space // Internal helper function to allow other parts of the codebase to check the total used disk space
// as needed without overly taxing the system. This will prioritize the value from the cache to avoid // as needed without overly taxing the system. This will prioritize the value from the cache to avoid
// excessive IO usage. We will only walk the filesystem and determine the size of the directory if there // excessive IO usage. We will only walk the filesystem and determine the size of the directory if there

View File

@ -1,6 +1,7 @@
package server package server
import ( import (
"encoding/json"
"github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/environment"
"sync" "sync"
) )
@ -17,17 +18,34 @@ type ResourceUsage struct {
// The current server status. // The current server status.
State string `json:"state" default:"offline"` State string `json:"state" default:"offline"`
// The current disk space being used by the server. This is cached to prevent slow lookup // The current disk space being used by the server. This value is not guaranteed to be accurate
// issues on frequent refreshes. // at all times. It is "manually" set whenever server.Proc() is called. This is kind of just a
// hacky solution for now to avoid passing events all over the place.
Disk int64 `json:"disk_bytes"` Disk int64 `json:"disk_bytes"`
} }
// Alias the resource usage so that we don't infinitely recurse when marshaling the struct.
type IResourceUsage ResourceUsage
// Custom marshaler to ensure that the object is locked when we're converting it to JSON in
// order to avoid race conditions.
func (ru *ResourceUsage) MarshalJSON() ([]byte, error) {
ru.mu.Lock()
defer ru.mu.Unlock()
return json.Marshal(IResourceUsage(*ru))
}
// Returns the resource usage stats for the server instance. If the server is not running, only the // Returns the resource usage stats for the server instance. If the server is not running, only the
// disk space currently used will be returned. When the server is running all of the other stats will // disk space currently used will be returned. When the server is running all of the other stats will
// be returned. // be returned.
// //
// When a process is stopped all of the stats are zeroed out except for the disk. // When a process is stopped all of the stats are zeroed out except for the disk.
func (s *Server) Proc() *ResourceUsage { func (s *Server) Proc() *ResourceUsage {
s.resources.SetDisk(s.Filesystem().CachedUsage())
// Get a read lock on the resources at this point. Don't do this before setting
// the disk, otherwise you'll cause a deadlock.
s.resources.mu.RLock() s.resources.mu.RLock()
defer s.resources.mu.RUnlock() defer s.resources.mu.RUnlock()
@ -35,11 +53,9 @@ func (s *Server) Proc() *ResourceUsage {
} }
func (s *Server) emitProcUsage() { func (s *Server) emitProcUsage() {
s.resources.mu.RLock() if err := s.Events().PublishJson(StatsEvent, s.Proc()); err != nil {
if err := s.Events().PublishJson(StatsEvent, s.resources); err != nil {
s.Log().WithField("error", err).Warn("error while emitting server resource usage to listeners") s.Log().WithField("error", err).Warn("error while emitting server resource usage to listeners")
} }
s.resources.mu.RUnlock()
} }
// Returns the servers current state. // Returns the servers current state.