replace servers.servers singleton with server.Manager
This commit is contained in:
@@ -12,7 +12,9 @@ import (
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
type Middleware struct{}
|
||||
type Middleware struct {
|
||||
serverManager server.Manager
|
||||
}
|
||||
|
||||
// A custom handler function allowing for errors bubbled up by c.Error() to be returned in a
|
||||
// standardized format with tracking UUIDs on them for easier log searching.
|
||||
@@ -92,14 +94,19 @@ func (m *Middleware) RequireAuthorization() gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to fetch a server out of the servers collection stored in memory.
|
||||
//
|
||||
// This function should not be used in new controllers, prefer ExtractServer where
|
||||
// possible.
|
||||
func GetServer(uuid string) *server.Server {
|
||||
return server.GetServers().Find(func(s *server.Server) bool {
|
||||
return uuid == s.Id()
|
||||
})
|
||||
func (m *Middleware) WithServerManager() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
c.Set("servermanager", m.serverManager)
|
||||
}
|
||||
}
|
||||
|
||||
func ServerManagerFromContext(c *gin.Context) server.Manager {
|
||||
if s, ok := c.Get("servermanager"); ok {
|
||||
if srvs, ok := s.(server.Manager); ok {
|
||||
return srvs
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Ensure that the requested server exists in this setup. Returns a 404 if we cannot
|
||||
@@ -108,7 +115,7 @@ func (m *Middleware) ServerExists() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
u, err := uuid.Parse(c.Param("server"))
|
||||
if err == nil {
|
||||
if s := GetServer(u.String()); s != nil {
|
||||
if s := m.serverManager.Get(u.String()); s != nil {
|
||||
c.Set("server", s)
|
||||
c.Next()
|
||||
return
|
||||
|
||||
@@ -3,15 +3,18 @@ package router
|
||||
import (
|
||||
"github.com/apex/log"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
)
|
||||
|
||||
// Configures the routing infrastructure for this daemon instance.
|
||||
func Configure() *gin.Engine {
|
||||
func Configure(serverManager server.Manager) *gin.Engine {
|
||||
gin.SetMode("release")
|
||||
|
||||
m := Middleware{}
|
||||
m := Middleware{
|
||||
serverManager,
|
||||
}
|
||||
router := gin.New()
|
||||
router.Use(gin.Recovery(), m.ErrorHandler(), m.SetAccessControlHeaders())
|
||||
router.Use(gin.Recovery(), m.ErrorHandler(), m.SetAccessControlHeaders(), m.WithServerManager())
|
||||
// @todo log this into a different file so you can setup IP blocking for abusive requests and such.
|
||||
// This should still dump requests in debug mode since it does help with understanding the request
|
||||
// lifecycle and quickly seeing what was called leading to the logs. However, it isn't feasible to mix
|
||||
|
||||
@@ -14,13 +14,15 @@ import (
|
||||
|
||||
// Handle a download request for a server backup.
|
||||
func getDownloadBackup(c *gin.Context) {
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
|
||||
token := tokens.BackupPayload{}
|
||||
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
|
||||
NewTrackedError(err).Abort(c)
|
||||
return
|
||||
}
|
||||
|
||||
s := GetServer(token.ServerUuid)
|
||||
s := serverManager.Get(token.ServerUuid)
|
||||
if s == nil || !token.IsUniqueRequest() {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||
"error": "The requested resource was not found on this server.",
|
||||
@@ -57,13 +59,15 @@ func getDownloadBackup(c *gin.Context) {
|
||||
|
||||
// Handles downloading a specific file for a server.
|
||||
func getDownloadFile(c *gin.Context) {
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
|
||||
token := tokens.FilePayload{}
|
||||
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
|
||||
NewTrackedError(err).Abort(c)
|
||||
return
|
||||
}
|
||||
|
||||
s := GetServer(token.ServerUuid)
|
||||
s := serverManager.Get(token.ServerUuid)
|
||||
if s == nil || !token.IsUniqueRequest() {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||
"error": "The requested resource was not found on this server.",
|
||||
|
||||
@@ -22,7 +22,7 @@ type serverProcData struct {
|
||||
|
||||
// Returns a single server from the collection of servers.
|
||||
func getServer(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
c.JSON(http.StatusOK, serverProcData{
|
||||
ResourceUsage: s.Proc(),
|
||||
@@ -32,7 +32,7 @@ func getServer(c *gin.Context) {
|
||||
|
||||
// Returns the logs for a given server instance.
|
||||
func getServerLogs(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
l, _ := strconv.Atoi(c.DefaultQuery("size", "100"))
|
||||
if l <= 0 {
|
||||
@@ -59,7 +59,7 @@ func getServerLogs(c *gin.Context) {
|
||||
// things are happening, so theres no reason to sit and wait for a request to finish. We'll
|
||||
// just see over the socket if something isn't working correctly.
|
||||
func postServerPower(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Action server.PowerAction `json:"action"`
|
||||
@@ -109,7 +109,7 @@ func postServerPower(c *gin.Context) {
|
||||
|
||||
// Sends an array of commands to a running server instance.
|
||||
func postServerCommands(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
if running, err := s.Environment.IsRunning(); err != nil {
|
||||
NewServerError(err, s).Abort(c)
|
||||
@@ -140,7 +140,7 @@ func postServerCommands(c *gin.Context) {
|
||||
|
||||
// Updates information about a server internally.
|
||||
func patchServer(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
buf := bytes.Buffer{}
|
||||
buf.ReadFrom(c.Request.Body)
|
||||
@@ -157,7 +157,7 @@ func patchServer(c *gin.Context) {
|
||||
|
||||
// Performs a server installation in a background thread.
|
||||
func postServerInstall(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
go func(serv *server.Server) {
|
||||
if err := serv.Install(true); err != nil {
|
||||
@@ -170,7 +170,7 @@ func postServerInstall(c *gin.Context) {
|
||||
|
||||
// Reinstalls a server.
|
||||
func postServerReinstall(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
if s.ExecutingPowerAction() {
|
||||
c.AbortWithStatusJSON(http.StatusConflict, gin.H{
|
||||
@@ -191,6 +191,7 @@ func postServerReinstall(c *gin.Context) {
|
||||
// Deletes a server from the wings daemon and dissociate it's objects.
|
||||
func deleteServer(c *gin.Context) {
|
||||
s := ExtractServer(c)
|
||||
sm := ServerManagerFromContext(c)
|
||||
|
||||
// Immediately suspend the server to prevent a user from attempting
|
||||
// to start it while this process is running.
|
||||
@@ -234,10 +235,7 @@ func deleteServer(c *gin.Context) {
|
||||
}
|
||||
}(s.Filesystem().Path())
|
||||
|
||||
uuid := s.Id()
|
||||
server.GetServers().Remove(func(s2 *server.Server) bool {
|
||||
return s2.Id() == uuid
|
||||
})
|
||||
sm.Remove(s)
|
||||
|
||||
// Deallocate the reference to this server.
|
||||
s = nil
|
||||
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
// Backs up a server.
|
||||
func postServerBackup(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
data := &backup.Request{}
|
||||
// BindJSON sends 400 if the request fails, all we need to do is return
|
||||
@@ -57,7 +57,7 @@ func postServerBackup(c *gin.Context) {
|
||||
// a 404 error. The service calling this endpoint can make its own decisions as to how it wants
|
||||
// to handle that response.
|
||||
func deleteServerBackup(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
b, _, err := backup.LocateLocal(c.Param("backup"))
|
||||
if err != nil {
|
||||
|
||||
@@ -76,7 +76,7 @@ type renameFile struct {
|
||||
|
||||
// Renames (or moves) files for a server.
|
||||
func putServerRenameFiles(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Root string `json:"root"`
|
||||
@@ -138,7 +138,7 @@ func putServerRenameFiles(c *gin.Context) {
|
||||
|
||||
// Copies a server file.
|
||||
func postServerCopyFile(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Location string `json:"location"`
|
||||
@@ -158,7 +158,7 @@ func postServerCopyFile(c *gin.Context) {
|
||||
|
||||
// Deletes files from a server.
|
||||
func postServerDeleteFiles(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Root string `json:"root"`
|
||||
@@ -203,7 +203,7 @@ func postServerDeleteFiles(c *gin.Context) {
|
||||
|
||||
// Writes the contents of the request to a file on a server.
|
||||
func postServerWriteFile(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
f := c.Query("file")
|
||||
f = "/" + strings.TrimLeft(f, "/")
|
||||
@@ -300,7 +300,7 @@ func deleteServerPullRemoteFile(c *gin.Context) {
|
||||
|
||||
// Create a directory on a server.
|
||||
func postServerCreateDirectory(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Name string `json:"name"`
|
||||
@@ -327,7 +327,7 @@ func postServerCreateDirectory(c *gin.Context) {
|
||||
}
|
||||
|
||||
func postServerCompressFiles(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
RootPath string `json:"root"`
|
||||
@@ -365,7 +365,7 @@ func postServerCompressFiles(c *gin.Context) {
|
||||
}
|
||||
|
||||
func postServerDecompressFiles(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
RootPath string `json:"root"`
|
||||
@@ -433,7 +433,7 @@ type chmodFile struct {
|
||||
var errInvalidFileMode = errors.New("invalid file mode")
|
||||
|
||||
func postServerChmodFile(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
s := ExtractServer(c)
|
||||
|
||||
var data struct {
|
||||
Root string `json:"root"`
|
||||
@@ -497,13 +497,15 @@ func postServerChmodFile(c *gin.Context) {
|
||||
}
|
||||
|
||||
func postServerUploadFiles(c *gin.Context) {
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
|
||||
token := tokens.UploadPayload{}
|
||||
if err := tokens.ParseToken([]byte(c.Query("token")), &token); err != nil {
|
||||
NewTrackedError(err).Abort(c)
|
||||
return
|
||||
}
|
||||
|
||||
s := GetServer(token.ServerUuid)
|
||||
s := serverManager.Get(token.ServerUuid)
|
||||
if s == nil || !token.IsUniqueRequest() {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{
|
||||
"error": "The requested resource was not found on this server.",
|
||||
|
||||
@@ -12,7 +12,8 @@ import (
|
||||
|
||||
// Upgrades a connection to a websocket and passes events along between.
|
||||
func getServerWebsocket(c *gin.Context) {
|
||||
s := GetServer(c.Param("server"))
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
s := serverManager.Get(c.Param("server"))
|
||||
handler, err := websocket.GetHandler(s, c.Writer, c.Request)
|
||||
if err != nil {
|
||||
NewServerError(err, s).Abort(c)
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pterodactyl/wings/config"
|
||||
"github.com/pterodactyl/wings/installer"
|
||||
"github.com/pterodactyl/wings/server"
|
||||
"github.com/pterodactyl/wings/system"
|
||||
)
|
||||
|
||||
@@ -28,7 +27,8 @@ func getSystemInformation(c *gin.Context) {
|
||||
// Returns all of the servers that are registered and configured correctly on
|
||||
// this wings instance.
|
||||
func getAllServers(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, server.GetServers().All())
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
c.JSON(http.StatusOK, serverManager.GetAll())
|
||||
}
|
||||
|
||||
// Creates a new server on the wings daemon and begins the installation process
|
||||
@@ -52,7 +52,8 @@ func postCreateServer(c *gin.Context) {
|
||||
|
||||
// Plop that server instance onto the request so that it can be referenced in
|
||||
// requests from here-on out.
|
||||
server.GetServers().Add(install.Server())
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
serverManager.Add(install.Server())
|
||||
|
||||
// Begin the installation process in the background to not block the request
|
||||
// cycle. If there are any errors they will be logged and communicated back
|
||||
|
||||
@@ -323,19 +323,19 @@ func postTransfer(c *gin.Context) {
|
||||
i.Server().Events().Publish(server.TransferLogsEvent, output)
|
||||
}
|
||||
|
||||
serverManager := ServerManagerFromContext(c)
|
||||
|
||||
// Mark the server as transferring to prevent problems later on during the process and
|
||||
// then push the server into the global server collection for this instance.
|
||||
i.Server().SetTransferring(true)
|
||||
server.GetServers().Add(i.Server())
|
||||
serverManager.Add(i.Server())
|
||||
defer func(s *server.Server) {
|
||||
// In the event that this transfer call fails, remove the server from the global
|
||||
// server tracking so that we don't have a dangling instance.
|
||||
if err := data.sendTransferStatus(!hasError); hasError || err != nil {
|
||||
sendTransferLog("Server transfer failed, check Wings logs for additional information.")
|
||||
s.Events().Publish(server.TransferStatusEvent, "failure")
|
||||
server.GetServers().Remove(func(s2 *server.Server) bool {
|
||||
return s.Id() == s2.Id()
|
||||
})
|
||||
serverManager.Remove(s)
|
||||
|
||||
// If the transfer status was successful but the request failed, act like the transfer failed.
|
||||
if !hasError && err != nil {
|
||||
|
||||
Reference in New Issue
Block a user