From 3b5e042ccc267422e18d914edd52ec49100b3137 Mon Sep 17 00:00:00 2001 From: Dane Everitt Date: Sun, 29 Aug 2021 14:08:01 -0700 Subject: [PATCH] Simplify logic when creating a new installer; no longer requires an entire server object be passed. --- CHANGELOG.md | 1 + installer/installer.go | 45 +++++++++++---------------------------- router/router_system.go | 23 ++++++++++---------- router/router_transfer.go | 9 ++++---- server/configuration.go | 2 -- 5 files changed, 28 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c919557..676c71d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ ### Changed * Releases are now built using `Go 1.17` — the minimum version required to build Wings remains `Go 1.16`. * Simplifed the logic powering server updates to only pull information from the Panel rather than trying to accept updated values. All parts of Wings needing the most up-to-date server details should call `Server#Sync()` to fetch the latest stored build information. +* `Installer#New()` no longer requires passing all of the server data as a byte slice, rather a new `Installer#ServerDetails` struct is exposed which can be passed and accepts a UUID and if the server should be started after the installer finishes. ### Removed * Removes complicated (and unused) logic during the server installation process that was a hold-over from legacy Wings architectures. diff --git a/installer/installer.go b/installer/installer.go index c34bdef..e4616e0 100644 --- a/installer/installer.go +++ b/installer/installer.go @@ -5,26 +5,29 @@ import ( "emperror.dev/errors" "github.com/asaskevich/govalidator" - "github.com/buger/jsonparser" - "github.com/pterodactyl/wings/remote" "github.com/pterodactyl/wings/server" ) type Installer struct { - server *server.Server + server *server.Server + StartOnCompletion bool +} + +type ServerDetails struct { + UUID string `json:"uuid"` + StartOnCompletion bool `json:"start_on_completion"` } // New validates the received data to ensure that all the required fields // have been passed along in the request. This should be manually run before // calling Execute(). -func New(ctx context.Context, manager *server.Manager, data []byte) (*Installer, error) { - uuid := getString(data, "uuid") - if !govalidator.IsUUIDv4(uuid) { +func New(ctx context.Context, manager *server.Manager, details ServerDetails) (*Installer, error) { + if !govalidator.IsUUIDv4(details.UUID) { return nil, NewValidationError("uuid provided was not in a valid format") } - c, err := manager.Client().GetServerConfiguration(ctx, uuid) + c, err := manager.Client().GetServerConfiguration(ctx, details.UUID) if err != nil { if !remote.IsRequestError(err) { return nil, errors.WithStackIf(err) @@ -38,35 +41,11 @@ func New(ctx context.Context, manager *server.Manager, data []byte) (*Installer, if err != nil { return nil, errors.WrapIf(err, "installer: could not init server instance") } - return &Installer{server: s}, nil -} - -// Uuid returns the UUID associated with this installer instance. -func (i *Installer) Uuid() string { - return i.server.ID() + i := Installer{server: s, StartOnCompletion: details.StartOnCompletion} + return &i, nil } // Server returns the server instance. func (i *Installer) Server() *server.Server { return i.server } - -// Returns a string value from the JSON data provided. -func getString(data []byte, key ...string) string { - value, _ := jsonparser.GetString(data, key...) - - return value -} - -// Returns an int value from the JSON data provided. -func getInt(data []byte, key ...string) int64 { - value, _ := jsonparser.GetInt(data, key...) - - return value -} - -func getBoolean(data []byte, key ...string) bool { - value, _ := jsonparser.GetBoolean(data, key...) - - return value -} diff --git a/router/router_system.go b/router/router_system.go index 95fdb6c..2f384af 100644 --- a/router/router_system.go +++ b/router/router_system.go @@ -1,7 +1,6 @@ package router import ( - "bytes" "context" "errors" "net/http" @@ -44,10 +43,13 @@ func getAllServers(c *gin.Context) { // for it. func postCreateServer(c *gin.Context) { manager := middleware.ExtractManager(c) - buf := bytes.Buffer{} - buf.ReadFrom(c.Request.Body) - install, err := installer.New(c.Request.Context(), manager, buf.Bytes()) + details := installer.ServerDetails{} + if err := c.BindJSON(&details); err != nil { + return + } + + install, err := installer.New(c.Request.Context(), manager, details) if err != nil { if installer.IsValidationError(err) { c.AbortWithStatusJSON(http.StatusUnprocessableEntity, gin.H{ @@ -74,24 +76,21 @@ func postCreateServer(c *gin.Context) { } if err := i.Server().Install(false); err != nil { - log.WithFields(log.Fields{"server": i.Uuid(), "error": err}).Error("failed to run install process for server") + log.WithFields(log.Fields{"server": i.Server().ID(), "error": err}).Error("failed to run install process for server") return } - if i.Server().Config().StartOnCompletion { + if i.StartOnCompletion { log.WithField("server_id", i.Server().ID()).Debug("starting server after successful installation") if err := i.Server().HandlePowerAction(server.PowerActionStart, 30); err != nil { if errors.Is(err, context.DeadlineExceeded) { - log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start"}). - Warn("could not acquire a lock while attempting to perform a power action") + log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start"}).Warn("could not acquire a lock while attempting to perform a power action") } else { - log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start", "error": err}). - Error("encountered error processing a server power action in the background") + log.WithFields(log.Fields{"server_id": i.Server().ID(), "action": "start", "error": err}).Error("encountered error processing a server power action in the background") } } } else { - log.WithField("server_id", i.Server().ID()). - Debug("skipping automatic start after successful server installation") + log.WithField("server_id", i.Server().ID()).Debug("skipping automatic start after successful server installation") } }(install) diff --git a/router/router_transfer.go b/router/router_transfer.go index 8c16cd8..794981e 100644 --- a/router/router_transfer.go +++ b/router/router_transfer.go @@ -5,7 +5,6 @@ import ( "context" "crypto/sha256" "encoding/hex" - "encoding/json" "fmt" "io" "net/http" @@ -47,10 +46,10 @@ type downloadProgress struct { // Data passed over to initiate a server transfer. type serverTransferRequest struct { - ServerID string `binding:"required" json:"server_id"` - URL string `binding:"required" json:"url"` - Token string `binding:"required" json:"token"` - Server json.RawMessage `json:"server"` + ServerID string `binding:"required" json:"server_id"` + URL string `binding:"required" json:"url"` + Token string `binding:"required" json:"token"` + Server installer.ServerDetails `json:"server"` } func getArchivePath(sID string) string { diff --git a/server/configuration.go b/server/configuration.go index dfc9ac5..64bab10 100644 --- a/server/configuration.go +++ b/server/configuration.go @@ -35,8 +35,6 @@ type Configuration struct { // server, specific installation scripts will be skipped for the server process. SkipEggScripts bool `json:"skip_egg_scripts"` - StartOnCompletion bool `json:"start_on_completion"` - // An array of environment variables that should be passed along to the running // server process. EnvVars environment.Variables `json:"environment"`