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

View File

@ -8,7 +8,7 @@ import (
"github.com/docker/docker/client"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/api"
"github.com/pterodactyl/wings/system"
"github.com/pterodactyl/wings/environment"
"os"
"strings"
"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
// 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...
e.setState(system.ProcessStoppingState)
e.setState(system.ProcessOfflineState)
e.setState(environment.ProcessStoppingState)
e.setState(environment.ProcessOfflineState)
}
}()
@ -74,7 +74,7 @@ func (e *Environment) Start() error {
} else {
// If the server is running update our internal state and continue on with the attach.
if c.State.Running {
e.setState(system.ProcessRunningState)
e.setState(environment.ProcessRunningState)
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
// 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
// it is and continue through to the stop handling for the process.
if e.State() != system.ProcessOfflineState {
e.setState(system.ProcessStoppingState)
if e.State() != environment.ProcessOfflineState {
e.setState(environment.ProcessStoppingState)
}
// 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.
if client.IsErrNotFound(err) {
e.SetStream(nil)
e.setState(system.ProcessOfflineState)
e.setState(environment.ProcessOfflineState)
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
// and update things to indicate we should be completely stopped now. Set to stopping
// first so crash detection is not triggered.
if e.State() != system.ProcessOfflineState {
e.setState(system.ProcessStoppingState)
e.setState(system.ProcessOfflineState)
if e.State() != environment.ProcessOfflineState {
e.setState(environment.ProcessStoppingState)
e.setState(environment.ProcessOfflineState)
}
return nil
}
// 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")
@ -226,7 +226,7 @@ func (e *Environment) Terminate(signal os.Signal) error {
return err
}
e.setState(system.ProcessOfflineState)
e.setState(environment.ProcessOfflineState)
return nil
}

View File

@ -4,7 +4,6 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/system"
)
// 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
// take their own actions and track their own state based on the environment.
func (e *Environment) setState(state string) error {
if state != system.ProcessOfflineState &&
state != system.ProcessStartingState &&
state != system.ProcessRunningState &&
state != system.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))
}

View File

@ -7,7 +7,6 @@ import (
"github.com/docker/docker/api/types"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/system"
"io"
"math"
"sync/atomic"
@ -16,7 +15,7 @@ import (
// Attach to the instance and then automatically emit an event whenever the resource usage for the
// server process changes.
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")
}
@ -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.
if e.State() == system.ProcessOfflineState {
if e.State() == environment.ProcessOfflineState {
return nil
}

View File

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

View File

@ -10,6 +10,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/router/tokens"
"github.com/pterodactyl/wings/server"
"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,
// Environment#EnableResourcePolling() will send this data to all clients.
if state == server.ProcessOfflineState {
if state == environment.ProcessOfflineState {
_ = h.server.Filesystem.HasSpaceAvailable()
b, _ := json.Marshal(h.server.Proc())
@ -328,7 +329,7 @@ func (h *Handler) HandleInbound(m Message) error {
return nil
}
if h.server.GetState() == server.ProcessOfflineState {
if h.server.GetState() == environment.ProcessOfflineState {
return nil
}

View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"sync"
"time"
)
@ -44,7 +45,7 @@ func (s *Server) handleServerCrash() error {
// 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
// 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 {
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/pterodactyl/wings/api"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"golang.org/x/sync/semaphore"
"html/template"
"io"
@ -58,9 +59,8 @@ func (s *Server) Install(sync bool) error {
// 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.
// 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
// 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
// does not touch any existing files for the server, other than what the script modifies.
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")
if err := s.Environment.WaitForStop(10, true); err != nil {
return err

View File

@ -66,7 +66,7 @@ func (s *Server) onConsoleOutput(data string) {
processConfiguration := s.ProcessConfiguration()
// Check if the server is currently starting.
if s.GetState() == ProcessStartingState {
if s.GetState() == environment.ProcessStartingState {
// Check if we should strip ansi color codes.
if processConfiguration.Startup.StripAnsi {
// 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,
// set the server to that state. Only do this if the server is not currently stopped
// or stopping.
_ = s.SetState(ProcessRunningState)
_ = s.SetState(environment.ProcessRunningState)
break
}
}
@ -99,7 +99,7 @@ func (s *Server) onConsoleOutput(data string) {
stop := processConfiguration.Stop
if stop.Type == api.ProcessStopCommand && data == stop.Value {
_ = s.SetState(ProcessStoppingState)
_ = s.SetState(environment.ProcessOfflineState)
}
}
}

View File

@ -5,7 +5,7 @@ import (
"fmt"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/system"
"github.com/pterodactyl/wings/environment"
"io"
"io/ioutil"
"os"
@ -14,13 +14,6 @@ import (
var stateMutex sync.Mutex
const (
ProcessOfflineState = "offline"
ProcessStartingState = "starting"
ProcessRunningState = "running"
ProcessStoppingState = "stopping"
)
// Returns the state of the servers.
func getServerStates() (map[string]string, error) {
// 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
// well as reporting to event listeners for the server.
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))
}
@ -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
// views in the Panel correctly display 0.
if state == system.ProcessOfflineState {
if state == environment.ProcessOfflineState {
s.resources.mu.Lock()
s.resources.Empty()
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
// separate thread as to not block any actions currently taking place in the flow
// 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")
go func(server *Server) {
@ -146,5 +142,5 @@ func (s *Server) GetState() string {
func (s *Server) IsRunning() bool {
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/imdario/mergo"
"github.com/pkg/errors"
"github.com/pterodactyl/wings/environment"
)
// 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() {
// Check if the s is now suspended, and if so and the process is not terminated
// 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")
if err := s.Environment.WaitForStop(10, true); err != nil {

View File

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