Different implementation of multi-check for done
Co-Authored-By: Matthew Penner <me@matthewp.io>
This commit is contained in:
parent
1a4c6726c5
commit
642e6e6a96
66
api/process_configuration.go
Normal file
66
api/process_configuration.go
Normal file
|
@ -0,0 +1,66 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/apex/log"
|
||||
"github.com/pterodactyl/wings/parser"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type OutputLineMatcher struct {
|
||||
// The raw string to match against. This may or may not be prefixed with
|
||||
// regex: which indicates we want to match against the regex expression.
|
||||
raw string
|
||||
reg *regexp.Regexp
|
||||
}
|
||||
|
||||
// Determine if a given string "s" matches the given line.
|
||||
func (olm *OutputLineMatcher) Matches(s string) bool {
|
||||
if olm.reg == nil {
|
||||
return strings.Contains(s, olm.raw)
|
||||
}
|
||||
|
||||
return olm.reg.MatchString(s)
|
||||
}
|
||||
|
||||
// Return the matcher's raw comparison string.
|
||||
func (olm *OutputLineMatcher) String() string {
|
||||
return olm.raw
|
||||
}
|
||||
|
||||
// Unmarshal the startup lines into individual structs for easier matching abilities.
|
||||
func (olm *OutputLineMatcher) UnmarshalJSON(data []byte) error {
|
||||
if err := json.Unmarshal(data, &olm.raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(olm.raw, "regex:") && len(olm.raw) > 6 {
|
||||
r, err := regexp.Compile(strings.TrimPrefix(olm.raw, "regex:"))
|
||||
if err != nil {
|
||||
log.WithField("error", err).WithField("raw", olm.raw).Warn("failed to compile output line marked as being regex")
|
||||
}
|
||||
|
||||
olm.reg = r
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Defines the process configuration for a given server instance. This sets what the
|
||||
// daemon is looking for to mark a server as done starting, what to do when stopping,
|
||||
// and what changes to make to the configuration file for a server.
|
||||
type ProcessConfiguration struct {
|
||||
Startup struct {
|
||||
Done []*OutputLineMatcher `json:"done"`
|
||||
UserInteraction []string `json:"user_interaction"`
|
||||
StripAnsi bool `json:"strip_ansi"`
|
||||
} `json:"startup"`
|
||||
|
||||
Stop struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
} `json:"stop"`
|
||||
|
||||
ConfigurationFiles []parser.ConfigurationFile `json:"configs"`
|
||||
}
|
|
@ -4,7 +4,6 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/pterodactyl/wings/parser"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -26,24 +25,6 @@ type ServerConfigurationResponse struct {
|
|||
ProcessConfiguration *ProcessConfiguration `json:"process_configuration"`
|
||||
}
|
||||
|
||||
// Defines the process configuration for a given server instance. This sets what the
|
||||
// daemon is looking for to mark a server as done starting, what to do when stopping,
|
||||
// and what changes to make to the configuration file for a server.
|
||||
type ProcessConfiguration struct {
|
||||
Startup struct {
|
||||
Done []string `json:"done"`
|
||||
UserInteraction []string `json:"user_interaction"`
|
||||
StripAnsi bool `json:"strip_ansi"`
|
||||
} `json:"startup"`
|
||||
|
||||
Stop struct {
|
||||
Type string `json:"type"`
|
||||
Value string `json:"value"`
|
||||
} `json:"stop"`
|
||||
|
||||
ConfigurationFiles []parser.ConfigurationFile `json:"configs"`
|
||||
}
|
||||
|
||||
// Defines installation script information for a server process. This is used when
|
||||
// a server is installed for the first time, and when a server is marked for re-installation.
|
||||
type InstallationScript struct {
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"github.com/apex/log"
|
||||
"github.com/pterodactyl/wings/api"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Adds all of the internal event listeners we want to use for a server.
|
||||
|
@ -23,12 +21,7 @@ func (s *Server) AddEventListeners() {
|
|||
}()
|
||||
}
|
||||
|
||||
var (
|
||||
stripAnsiRegex = regexp.MustCompile("[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))")
|
||||
|
||||
regexpCacheMx sync.RWMutex
|
||||
regexpCache map[string]*regexp.Regexp
|
||||
)
|
||||
var stripAnsiRegex = regexp.MustCompile("[\u001B\u009B][[\\]()#;?]*(?:(?:(?:[a-zA-Z\\d]*(?:;[a-zA-Z\\d]*)*)?\u0007)|(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PRZcf-ntqry=><~]))")
|
||||
|
||||
// Custom listener for console output events that will check if the given line
|
||||
// of output matches one that should mark the server as started or not.
|
||||
|
@ -38,10 +31,6 @@ func (s *Server) onConsoleOutput(data string) {
|
|||
|
||||
// Check if the server is currently starting.
|
||||
if s.GetState() == ProcessStartingState {
|
||||
// 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.
|
||||
|
||||
// Check if we should strip ansi color codes.
|
||||
if processConfiguration.Startup.StripAnsi {
|
||||
// Strip ansi color codes from the data string.
|
||||
|
@ -49,40 +38,19 @@ func (s *Server) onConsoleOutput(data string) {
|
|||
}
|
||||
|
||||
// Iterate over all the done lines.
|
||||
for _, match := range processConfiguration.Startup.Done {
|
||||
if strings.HasPrefix(match, "regex:") && len(match) > 6 {
|
||||
match = match[6:]
|
||||
|
||||
regexpCacheMx.RLock()
|
||||
rxp, ok := regexpCache[match]
|
||||
regexpCacheMx.RUnlock()
|
||||
|
||||
if !ok {
|
||||
var err error
|
||||
|
||||
rxp, err = regexp.Compile(match)
|
||||
if err != nil {
|
||||
log.WithError(err).Warn("failed to compile regexp")
|
||||
break
|
||||
}
|
||||
|
||||
regexpCacheMx.Lock()
|
||||
regexpCache[match] = rxp
|
||||
regexpCacheMx.Unlock()
|
||||
}
|
||||
|
||||
if !rxp.MatchString(data) {
|
||||
continue
|
||||
}
|
||||
} else if !strings.Contains(data, match) {
|
||||
for _, l := range processConfiguration.Startup.Done {
|
||||
if !l.Matches(data) {
|
||||
continue
|
||||
}
|
||||
|
||||
s.Log().WithFields(log.Fields{
|
||||
"match": match,
|
||||
"match": l.String(),
|
||||
"against": data,
|
||||
}).Debug("detected server in running state based on console line output")
|
||||
|
||||
// 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)
|
||||
break
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user