2020-04-06 01:00:33 +00:00
package router
import (
2021-07-04 22:08:05 +00:00
"context"
"errors"
2021-01-10 01:22:39 +00:00
"net/http"
"strings"
2020-06-13 17:26:35 +00:00
"github.com/apex/log"
2020-04-06 01:00:33 +00:00
"github.com/gin-gonic/gin"
2021-08-02 21:07:00 +00:00
2020-04-11 23:17:46 +00:00
"github.com/pterodactyl/wings/config"
2021-01-26 04:28:24 +00:00
"github.com/pterodactyl/wings/router/middleware"
2021-04-03 18:08:26 +00:00
"github.com/pterodactyl/wings/server"
2022-11-15 01:25:01 +00:00
"github.com/pterodactyl/wings/server/installer"
2020-04-06 01:00:33 +00:00
"github.com/pterodactyl/wings/system"
)
// Returns information about the system that wings is running on.
func getSystemInformation ( c * gin . Context ) {
i , err := system . GetSystemInformation ( )
if err != nil {
2022-11-22 18:18:27 +00:00
middleware . CaptureAndAbort ( c , err )
2022-11-21 23:01:14 +00:00
return
}
2020-04-06 01:00:33 +00:00
2022-11-21 23:01:14 +00:00
if c . Query ( "v" ) == "2" {
c . JSON ( http . StatusOK , i )
2020-04-06 01:00:33 +00:00
return
}
2022-11-21 23:01:14 +00:00
c . JSON ( http . StatusOK , struct {
Architecture string ` json:"architecture" `
CPUCount int ` json:"cpu_count" `
KernelVersion string ` json:"kernel_version" `
OS string ` json:"os" `
Version string ` json:"version" `
} {
Architecture : i . System . Architecture ,
CPUCount : i . System . CPUThreads ,
KernelVersion : i . System . KernelVersion ,
OS : i . System . OSType ,
Version : i . Version ,
} )
2020-04-06 01:00:33 +00:00
}
2022-11-15 01:25:01 +00:00
// Returns all the servers that are registered and configured correctly on
2020-04-06 01:00:33 +00:00
// this wings instance.
func getAllServers ( c * gin . Context ) {
2021-04-02 19:32:30 +00:00
servers := middleware . ExtractManager ( c ) . All ( )
2021-04-04 17:20:27 +00:00
out := make ( [ ] server . APIResponse , len ( servers ) , len ( servers ) )
2021-04-03 18:08:26 +00:00
for i , v := range servers {
2021-04-04 17:20:27 +00:00
out [ i ] = v . ToAPIResponse ( )
2021-04-02 19:32:30 +00:00
}
2021-04-03 18:08:26 +00:00
c . JSON ( http . StatusOK , out )
2020-04-06 01:00:33 +00:00
}
// Creates a new server on the wings daemon and begins the installation process
// for it.
func postCreateServer ( c * gin . Context ) {
2021-02-02 05:28:46 +00:00
manager := middleware . ExtractManager ( c )
2020-04-06 01:00:33 +00:00
2021-08-29 21:08:01 +00:00
details := installer . ServerDetails { }
if err := c . BindJSON ( & details ) ; err != nil {
return
}
install , err := installer . New ( c . Request . Context ( ) , manager , details )
2020-04-06 01:00:33 +00:00
if err != nil {
2020-04-12 00:55:00 +00:00
if installer . IsValidationError ( err ) {
c . AbortWithStatusJSON ( http . StatusUnprocessableEntity , gin . H {
"error" : "The data provided in the request could not be validated." ,
} )
return
}
2021-03-04 05:00:58 +00:00
middleware . CaptureAndAbort ( c , err )
2020-04-06 01:00:33 +00:00
return
}
// Plop that server instance onto the request so that it can be referenced in
// requests from here-on out.
2021-01-26 04:28:24 +00:00
manager . Add ( install . Server ( ) )
2020-04-06 01:00:33 +00:00
// 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
// to the Panel where a reinstall may take place.
go func ( i * installer . Installer ) {
2021-07-04 22:08:05 +00:00
if err := i . Server ( ) . CreateEnvironment ( ) ; err != nil {
2020-09-13 04:48:04 +00:00
i . Server ( ) . Log ( ) . WithField ( "error" , err ) . Error ( "failed to create server environment during install process" )
return
}
2020-04-06 01:00:33 +00:00
2022-11-21 21:57:44 +00:00
if err := i . Server ( ) . Install ( ) ; err != nil {
2021-08-29 21:08:01 +00:00
log . WithFields ( log . Fields { "server" : i . Server ( ) . ID ( ) , "error" : err } ) . Error ( "failed to run install process for server" )
2021-07-04 22:08:05 +00:00
return
}
2021-08-29 21:08:01 +00:00
if i . StartOnCompletion {
2021-08-02 21:07:00 +00:00
log . WithField ( "server_id" , i . Server ( ) . ID ( ) ) . Debug ( "starting server after successful installation" )
2021-07-04 22:08:05 +00:00
if err := i . Server ( ) . HandlePowerAction ( server . PowerActionStart , 30 ) ; err != nil {
if errors . Is ( err , context . DeadlineExceeded ) {
2021-08-29 21:08:01 +00:00
log . WithFields ( log . Fields { "server_id" : i . Server ( ) . ID ( ) , "action" : "start" } ) . Warn ( "could not acquire a lock while attempting to perform a power action" )
2021-07-04 22:08:05 +00:00
} else {
2021-08-29 21:08:01 +00:00
log . WithFields ( log . Fields { "server_id" : i . Server ( ) . ID ( ) , "action" : "start" , "error" : err } ) . Error ( "encountered error processing a server power action in the background" )
2021-07-04 22:08:05 +00:00
}
}
} else {
2021-08-29 21:08:01 +00:00
log . WithField ( "server_id" , i . Server ( ) . ID ( ) ) . Debug ( "skipping automatic start after successful server installation" )
2020-04-06 01:00:33 +00:00
}
} ( install )
c . Status ( http . StatusAccepted )
2020-04-06 20:39:33 +00:00
}
2020-04-11 23:17:46 +00:00
2021-01-15 04:32:38 +00:00
// Updates the running configuration for this Wings instance.
2020-04-11 23:17:46 +00:00
func postUpdateConfiguration ( c * gin . Context ) {
2021-01-15 04:32:38 +00:00
cfg := config . Get ( )
2020-05-29 15:44:49 +00:00
if err := c . BindJSON ( & cfg ) ; err != nil {
return
}
2022-01-18 03:22:13 +00:00
2020-06-30 03:56:13 +00:00
// Keep the SSL certificates the same since the Panel will send through Lets Encrypt
// default locations. However, if we picked a different location manually we don't
// want to override that.
//
// If you pass through manual locations in the API call this logic will be skipped.
if strings . HasPrefix ( cfg . Api . Ssl . KeyFile , "/etc/letsencrypt/live/" ) {
2022-01-18 03:22:13 +00:00
cfg . Api . Ssl . KeyFile = config . Get ( ) . Api . Ssl . KeyFile
cfg . Api . Ssl . CertificateFile = config . Get ( ) . Api . Ssl . CertificateFile
2020-06-30 03:56:13 +00:00
}
2022-01-18 03:22:13 +00:00
2021-01-15 04:32:38 +00:00
// Try to write this new configuration to the disk before updating our global
// state with it.
if err := config . WriteToDisk ( cfg ) ; err != nil {
2022-11-22 18:18:27 +00:00
middleware . CaptureAndAbort ( c , err )
2020-04-11 23:17:46 +00:00
return
}
2021-01-15 04:32:38 +00:00
// Since we wrote it to the disk successfully now update the global configuration
// state to use this new configuration struct.
config . Set ( cfg )
2020-04-11 23:17:46 +00:00
c . Status ( http . StatusNoContent )
2020-05-29 15:44:49 +00:00
}