Use environment namespace for power state, don't duplicate them across server

This commit is contained in:
Dane Everitt 2020-08-19 18:58:48 -07:00
parent b9fb922e91
commit 4d3a860604
No known key found for this signature in database
GPG Key ID: EEA66103B3D71F53
13 changed files with 51 additions and 55 deletions

View File

@ -208,7 +208,7 @@ func rootCmdRun(*cobra.Command, []string) {
// Addresses potentially invalid data in the stored file that can cause Wings to lose // Addresses potentially invalid data in the stored file that can cause Wings to lose
// track of what the actual server state is. // track of what the actual server state is.
_ = s.SetState(server.ProcessOfflineState) _ = s.SetState(environment.ProcessOfflineState)
}) })
} }

View File

@ -13,7 +13,6 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/system"
"io" "io"
"strconv" "strconv"
"strings" "strings"
@ -54,7 +53,7 @@ func (e *Environment) Attach() error {
defer cancel() defer cancel()
defer e.stream.Close() defer e.stream.Close()
defer func() { defer func() {
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
e.SetStream(nil) e.SetStream(nil)
}() }()
@ -230,7 +229,7 @@ func (e *Environment) convertMounts() []mount.Mount {
// 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 triggeree.
e.setState(system.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{
RemoveVolumes: true, RemoveVolumes: true,
@ -246,7 +245,7 @@ func (e *Environment) Destroy() error {
return nil return nil
} }
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
return err return err
} }

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/docker/client" "github.com/docker/docker/client"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/api" "github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/system" "github.com/pterodactyl/wings/environment"
"os" "os"
"strings" "strings"
"time" "time"
@ -57,8 +57,8 @@ func (e *Environment) Start() error {
// If we don't set it to stopping first, you'll trigger crash detection which // If we don't set it to stopping first, you'll trigger crash detection which
// we don't want to do at this point since it'll just immediately try to do the // we don't want to do at this point since it'll just immediately try to do the
// exact same action that lead to it crashing in the first place... // exact same action that lead to it crashing in the first place...
e.setState(system.ProcessStoppingState) e.setState(environment.ProcessStoppingState)
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
} }
}() }()
@ -74,7 +74,7 @@ func (e *Environment) Start() error {
} else { } else {
// If the server is running update our internal state and continue on with the attach. // If the server is running update our internal state and continue on with the attach.
if c.State.Running { if c.State.Running {
e.setState(system.ProcessRunningState) e.setState(environment.ProcessRunningState)
return e.Attach() return e.Attach()
} }
@ -89,7 +89,7 @@ func (e *Environment) Start() error {
} }
} }
e.setState(system.ProcessStartingState) e.setState(environment.ProcessStartingState)
// Set this to true for now, we will set it to false once we reach the // Set this to true for now, we will set it to false once we reach the
// end of this chain. // end of this chain.
@ -136,8 +136,8 @@ func (e *Environment) Stop() error {
// If the process is already offline don't switch it back to stopping. Just leave it how // If the process is already offline don't switch it back to stopping. Just leave it how
// it is and continue through to the stop handling for the process. // it is and continue through to the stop handling for the process.
if e.State() != system.ProcessOfflineState { if e.State() != environment.ProcessOfflineState {
e.setState(system.ProcessStoppingState) e.setState(environment.ProcessStoppingState)
} }
// Only attempt to send the stop command to the instance if we are actually attached to // Only attempt to send the stop command to the instance if we are actually attached to
@ -153,7 +153,7 @@ func (e *Environment) Stop() error {
// an error. // an error.
if client.IsErrNotFound(err) { if client.IsErrNotFound(err) {
e.SetStream(nil) e.SetStream(nil)
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
return nil return nil
} }
@ -209,16 +209,16 @@ func (e *Environment) Terminate(signal os.Signal) error {
// If the container is not running but we're not already in a stopped state go ahead // If the container is not running but we're not already in a stopped state go ahead
// and update things to indicate we should be completely stopped now. Set to stopping // and update things to indicate we should be completely stopped now. Set to stopping
// first so crash detection is not triggered. // first so crash detection is not triggered.
if e.State() != system.ProcessOfflineState { if e.State() != environment.ProcessOfflineState {
e.setState(system.ProcessStoppingState) e.setState(environment.ProcessStoppingState)
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
} }
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 triggeree.
e.setState(system.ProcessStoppingState) e.setState(environment.ProcessStoppingState)
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed") sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
@ -226,7 +226,7 @@ func (e *Environment) Terminate(signal os.Signal) error {
return err return err
} }
e.setState(system.ProcessOfflineState) e.setState(environment.ProcessOfflineState)
return nil return nil
} }

View File

@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/system"
) )
// Returns the current environment state. // Returns the current environment state.
@ -18,10 +17,10 @@ func (e *Environment) State() string {
// Sets the state of the environment. This emits an event that server's can hook into to // Sets the state of the environment. This emits an event that server's can hook into to
// take their own actions and track their own state based on the environment. // take their own actions and track their own state based on the environment.
func (e *Environment) setState(state string) error { func (e *Environment) setState(state string) error {
if state != system.ProcessOfflineState && if state != environment.ProcessOfflineState &&
state != system.ProcessStartingState && state != environment.ProcessStartingState &&
state != system.ProcessRunningState && state != environment.ProcessRunningState &&
state != system.ProcessStoppingState { state != environment.ProcessStoppingState {
return errors.New(fmt.Sprintf("invalid server state received: %s", state)) return errors.New(fmt.Sprintf("invalid server state received: %s", state))
} }

View File

@ -7,7 +7,6 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/environment" "github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/system"
"io" "io"
"math" "math"
"sync/atomic" "sync/atomic"
@ -16,7 +15,7 @@ import (
// Attach to the instance and then automatically emit an event whenever the resource usage for the // Attach to the instance and then automatically emit an event whenever the resource usage for the
// server process changes. // server process changes.
func (e *Environment) pollResources(ctx context.Context) error { func (e *Environment) pollResources(ctx context.Context) error {
if e.State() == system.ProcessOfflineState { if e.State() == environment.ProcessOfflineState {
return errors.New("attempting to enable resource polling on a stopped server instance") return errors.New("attempting to enable resource polling on a stopped server instance")
} }
@ -43,7 +42,7 @@ func (e *Environment) pollResources(ctx context.Context) error {
} }
// Disable collection if the server is in an offline state and this process is still running. // Disable collection if the server is in an offline state and this process is still running.
if e.State() == system.ProcessOfflineState { if e.State() == environment.ProcessOfflineState {
return nil return nil
} }

View File

@ -11,6 +11,13 @@ const (
ResourceEvent = "resources" ResourceEvent = "resources"
) )
const (
ProcessOfflineState = "offline"
ProcessStartingState = "starting"
ProcessRunningState = "running"
ProcessStoppingState = "stopping"
)
// Defines the basic interface that all environments need to implement so that // Defines the basic interface that all environments need to implement so that
// a server can be properly controlled. // a server can be properly controlled.
type ProcessEnvironment interface { type ProcessEnvironment interface {

View File

@ -10,6 +10,7 @@ import (
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/router/tokens" "github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server" "github.com/pterodactyl/wings/server"
"net/http" "net/http"
@ -259,7 +260,7 @@ func (h *Handler) HandleInbound(m Message) error {
// Only send the current disk usage if the server is offline, if docker container is running, // Only send the current disk usage if the server is offline, if docker container is running,
// Environment#EnableResourcePolling() will send this data to all clients. // Environment#EnableResourcePolling() will send this data to all clients.
if state == server.ProcessOfflineState { if state == environment.ProcessOfflineState {
_ = h.server.Filesystem.HasSpaceAvailable() _ = h.server.Filesystem.HasSpaceAvailable()
b, _ := json.Marshal(h.server.Proc()) b, _ := json.Marshal(h.server.Proc())
@ -328,7 +329,7 @@ func (h *Handler) HandleInbound(m Message) error {
return nil return nil
} }
if h.server.GetState() == server.ProcessOfflineState { if h.server.GetState() == environment.ProcessOfflineState {
return nil return nil
} }

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"sync" "sync"
"time" "time"
) )
@ -44,7 +45,7 @@ func (s *Server) handleServerCrash() error {
// No point in doing anything here if the server isn't currently offline, there // No point in doing anything here if the server isn't currently offline, there
// is no reason to do a crash detection event. If the server crash detection is // is no reason to do a crash detection event. If the server crash detection is
// disabled we want to skip anything after this as well. // disabled we want to skip anything after this as well.
if s.GetState() != ProcessOfflineState || !s.Config().CrashDetectionEnabled { if s.GetState() != environment.ProcessOfflineState || !s.Config().CrashDetectionEnabled {
if !s.Config().CrashDetectionEnabled { if !s.Config().CrashDetectionEnabled {
s.Log().Debug("server triggered crash detection but handler is disabled for server process") s.Log().Debug("server triggered crash detection but handler is disabled for server process")

View File

@ -12,6 +12,7 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/api" "github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"golang.org/x/sync/semaphore" "golang.org/x/sync/semaphore"
"html/template" "html/template"
"io" "io"
@ -58,9 +59,8 @@ func (s *Server) Install(sync bool) error {
// Some how these publish events are sent to clients in reverse order, // Some how these publish events are sent to clients in reverse order,
// this is probably due to channels having the most recently sent item first. // this is probably due to channels having the most recently sent item first.
// Ensure that the server is marked as offline. // Ensure that the server is marked as offline.
s.Events().Publish(StatusEvent, ProcessOfflineState) s.Events().Publish(StatusEvent, environment.ProcessOfflineState)
// Push an event to the websocket so we can auto-refresh the information in the panel once // Push an event to the websocket so we can auto-refresh the information in the panel once
// the install is completed. // the install is completed.
@ -72,7 +72,7 @@ func (s *Server) Install(sync bool) error {
// Reinstalls a server's software by utilizing the install script for the server egg. This // Reinstalls a server's software by utilizing the install script for the server egg. This
// does not touch any existing files for the server, other than what the script modifies. // does not touch any existing files for the server, other than what the script modifies.
func (s *Server) Reinstall() error { func (s *Server) Reinstall() error {
if s.GetState() != ProcessOfflineState { if s.GetState() != environment.ProcessOfflineState {
s.Log().Debug("waiting for server instance to enter a stopped state") s.Log().Debug("waiting for server instance to enter a stopped state")
if err := s.Environment.WaitForStop(10, true); err != nil { if err := s.Environment.WaitForStop(10, true); err != nil {
return err return err

View File

@ -66,7 +66,7 @@ func (s *Server) onConsoleOutput(data string) {
processConfiguration := s.ProcessConfiguration() processConfiguration := s.ProcessConfiguration()
// Check if the server is currently starting. // Check if the server is currently starting.
if s.GetState() == ProcessStartingState { if s.GetState() == environment.ProcessStartingState {
// Check if we should strip ansi color codes. // Check if we should strip ansi color codes.
if processConfiguration.Startup.StripAnsi { if processConfiguration.Startup.StripAnsi {
// Strip ansi color codes from the data string. // Strip ansi color codes from the data string.
@ -87,7 +87,7 @@ func (s *Server) onConsoleOutput(data string) {
// If the specific line of output is one that would mark the server as started, // If the specific line of output is one that would mark the server as started,
// set the server to that state. Only do this if the server is not currently stopped // set the server to that state. Only do this if the server is not currently stopped
// or stopping. // or stopping.
_ = s.SetState(ProcessRunningState) _ = s.SetState(environment.ProcessRunningState)
break break
} }
} }
@ -99,7 +99,7 @@ func (s *Server) onConsoleOutput(data string) {
stop := processConfiguration.Stop stop := processConfiguration.Stop
if stop.Type == api.ProcessStopCommand && data == stop.Value { if stop.Type == api.ProcessStopCommand && data == stop.Value {
_ = s.SetState(ProcessStoppingState) _ = s.SetState(environment.ProcessOfflineState)
} }
} }
} }

View File

@ -5,7 +5,7 @@ import (
"fmt" "fmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/config" "github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system" "github.com/pterodactyl/wings/environment"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
@ -14,13 +14,6 @@ import (
var stateMutex sync.Mutex var stateMutex sync.Mutex
const (
ProcessOfflineState = "offline"
ProcessStartingState = "starting"
ProcessRunningState = "running"
ProcessStoppingState = "stopping"
)
// Returns the state of the servers. // Returns the state of the servers.
func getServerStates() (map[string]string, error) { func getServerStates() (map[string]string, error) {
// Request a lock after we check if the file exists. // Request a lock after we check if the file exists.
@ -71,7 +64,10 @@ func saveServerStates() error {
// Sets the state of the server internally. This function handles crash detection as // Sets the state of the server internally. This function handles crash detection as
// well as reporting to event listeners for the server. // well as reporting to event listeners for the server.
func (s *Server) SetState(state string) error { func (s *Server) SetState(state string) error {
if state != ProcessOfflineState && state != ProcessStartingState && state != ProcessRunningState && state != ProcessStoppingState { if state != environment.ProcessOfflineState &&
state != environment.ProcessStartingState &&
state != environment.ProcessRunningState &&
state != environment.ProcessStoppingState {
return errors.New(fmt.Sprintf("invalid server state received: %s", state)) return errors.New(fmt.Sprintf("invalid server state received: %s", state))
} }
@ -102,7 +98,7 @@ func (s *Server) SetState(state string) error {
// Reset the resource usage to 0 when the process fully stops so that all of the UI // Reset the resource usage to 0 when the process fully stops so that all of the UI
// views in the Panel correctly display 0. // views in the Panel correctly display 0.
if state == system.ProcessOfflineState { if state == environment.ProcessOfflineState {
s.resources.mu.Lock() s.resources.mu.Lock()
s.resources.Empty() s.resources.Empty()
s.resources.mu.Unlock() s.resources.mu.Unlock()
@ -118,7 +114,7 @@ func (s *Server) SetState(state string) error {
// automatically attempt to start the process back up for the user. This is done in a // automatically attempt to start the process back up for the user. This is done in a
// separate thread as to not block any actions currently taking place in the flow // separate thread as to not block any actions currently taking place in the flow
// that called this function. // that called this function.
if (prevState == ProcessStartingState || prevState == ProcessRunningState) && s.GetState() == ProcessOfflineState { if (prevState == environment.ProcessStartingState || prevState == environment.ProcessRunningState) && s.GetState() == environment.ProcessOfflineState {
s.Log().Info("detected server as entering a crashed state; running crash handler") s.Log().Info("detected server as entering a crashed state; running crash handler")
go func(server *Server) { go func(server *Server) {
@ -146,5 +142,5 @@ func (s *Server) GetState() string {
func (s *Server) IsRunning() bool { func (s *Server) IsRunning() bool {
st := s.GetState() st := s.GetState()
return st == ProcessRunningState || st == ProcessStartingState return st == environment.ProcessRunningState || st == environment.ProcessStartingState
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/buger/jsonparser" "github.com/buger/jsonparser"
"github.com/imdario/mergo" "github.com/imdario/mergo"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
) )
// Merges data passed through in JSON form into the existing server object. // Merges data passed through in JSON form into the existing server object.
@ -112,7 +113,7 @@ func (s *Server) UpdateDataStructure(data []byte, background bool) error {
func (s *Server) runBackgroundActions() { func (s *Server) runBackgroundActions() {
// Check if the s is now suspended, and if so and the process is not terminated // Check if the s is now suspended, and if so and the process is not terminated
// yet, do it immediately. // yet, do it immediately.
if s.IsSuspended() && s.GetState() != ProcessOfflineState { if s.IsSuspended() && s.GetState() != environment.ProcessOfflineState {
s.Log().Info("server suspended with running process state, terminating now") s.Log().Info("server suspended with running process state, terminating now")
if err := s.Environment.WaitForStop(10, true); err != nil { if err := s.Environment.WaitForStop(10, true); err != nil {

View File

@ -4,10 +4,3 @@ var (
// The current version of this software. // The current version of this software.
Version = "0.0.1" Version = "0.0.1"
) )
const (
ProcessOfflineState = "offline"
ProcessStartingState = "starting"
ProcessRunningState = "running"
ProcessStoppingState = "stopping"
)