Merge branch 'develop' of https://github.com/pterodactyl/wings into develop
This commit is contained in:
commit
044c46fc9a
|
@ -406,7 +406,7 @@ __ [blue][bold]Pterodactyl[reset] _____/___/_______ _______ ______
|
||||||
\_____\ \/\/ / / / __ / ___/
|
\_____\ \/\/ / / / __ / ___/
|
||||||
\___\ / / / / /_/ /___ /
|
\___\ / / / / /_/ /___ /
|
||||||
\___/\___/___/___/___/___ /______/
|
\___/\___/___/___/___/___ /______/
|
||||||
/_______/ [bold]v%s[reset]
|
/_______/ [bold]%s[reset]
|
||||||
|
|
||||||
Copyright © 2018 - 2021 Dane Everitt & Contributors
|
Copyright © 2018 - 2021 Dane Everitt & Contributors
|
||||||
|
|
||||||
|
|
|
@ -90,7 +90,7 @@ func (e *Environment) Attach() error {
|
||||||
|
|
||||||
// Block the completion of this routine until the container is no longer running. This allows
|
// Block the completion of this routine until the container is no longer running. This allows
|
||||||
// the pollResources function to run until it needs to be stopped. Because the container
|
// the pollResources function to run until it needs to be stopped. Because the container
|
||||||
// can be polled for resource usage, even when sropped, we need to have this logic present
|
// can be polled for resource usage, even when stopped, we need to have this logic present
|
||||||
// in order to cancel the context and therefore stop the routine that is spawned.
|
// in order to cancel the context and therefore stop the routine that is spawned.
|
||||||
//
|
//
|
||||||
// For now, DO NOT use client#ContainerWait from the Docker package. There is a nasty
|
// For now, DO NOT use client#ContainerWait from the Docker package. There is a nasty
|
||||||
|
@ -278,6 +278,8 @@ func (e *Environment) Destroy() error {
|
||||||
Force: true,
|
Force: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
e.SetState(environment.ProcessOfflineState)
|
||||||
|
|
||||||
// Don't trigger a destroy failure if we try to delete a container that does not
|
// Don't trigger a destroy failure if we try to delete a container that does not
|
||||||
// exist on the system. We're just a step ahead of ourselves in that case.
|
// exist on the system. We're just a step ahead of ourselves in that case.
|
||||||
//
|
//
|
||||||
|
@ -286,8 +288,6 @@ func (e *Environment) Destroy() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
e.SetState(environment.ProcessOfflineState)
|
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,19 +313,39 @@ func (e *Environment) followOutput() error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
go func(reader io.ReadCloser) {
|
|
||||||
defer reader.Close()
|
go e.scanOutput(reader)
|
||||||
evts := e.Events()
|
|
||||||
err := system.ScanReader(reader, func(line string) {
|
|
||||||
evts.Publish(environment.ConsoleOutputEvent, line)
|
|
||||||
})
|
|
||||||
if err != nil && err != io.EOF {
|
|
||||||
log.WithField("error", err).WithField("container_id", e.Id).Warn("error processing scanner line in console output")
|
|
||||||
}
|
|
||||||
}(reader)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *Environment) scanOutput(reader io.ReadCloser) {
|
||||||
|
defer reader.Close()
|
||||||
|
|
||||||
|
events := e.Events()
|
||||||
|
|
||||||
|
err := system.ScanReader(reader, func(line string) {
|
||||||
|
events.Publish(environment.ConsoleOutputEvent, line)
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
log.WithField("error", err).WithField("container_id", e.Id).Warn("error processing scanner line in console output")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return here if the server is offline or currently stopping.
|
||||||
|
if e.State() == environment.ProcessStoppingState || e.State() == environment.ProcessOfflineState {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the current reader before starting a new one, the defer will still run
|
||||||
|
// but it will do nothing if we already closed the stream.
|
||||||
|
_ = reader.Close()
|
||||||
|
|
||||||
|
// Start following the output of the server again.
|
||||||
|
go e.followOutput()
|
||||||
|
}
|
||||||
|
|
||||||
// Pulls the image from Docker. If there is an error while pulling the image from the source
|
// Pulls the image from Docker. If there is an error while pulling the image from the source
|
||||||
// but the image already exists locally, we will report that error to the logger but continue
|
// but the image already exists locally, we will report that error to the logger but continue
|
||||||
// with the process.
|
// with the process.
|
||||||
|
@ -409,9 +429,11 @@ func (e *Environment) ensureImageExists(image string) error {
|
||||||
// I'm not sure what the best approach here is, but this will block execution until the image
|
// I'm not sure what the best approach here is, but this will block execution until the image
|
||||||
// is done being pulled, which is what we need.
|
// is done being pulled, which is what we need.
|
||||||
scanner := bufio.NewScanner(out)
|
scanner := bufio.NewScanner(out)
|
||||||
|
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
s := imagePullStatus{}
|
s := imagePullStatus{}
|
||||||
fmt.Println(scanner.Text())
|
fmt.Println(scanner.Text())
|
||||||
|
|
||||||
if err := json.Unmarshal(scanner.Bytes(), &s); err == nil {
|
if err := json.Unmarshal(scanner.Bytes(), &s); err == nil {
|
||||||
e.Events().Publish(environment.DockerImagePullStatus, s.Status+" "+s.Progress)
|
e.Events().Publish(environment.DockerImagePullStatus, s.Status+" "+s.Progress)
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,9 @@ func (e *Environment) Type() string {
|
||||||
// Set if this process is currently attached to the process.
|
// Set if this process is currently attached to the process.
|
||||||
func (e *Environment) SetStream(s *types.HijackedResponse) {
|
func (e *Environment) SetStream(s *types.HijackedResponse) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
e.stream = s
|
e.stream = s
|
||||||
e.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine if the this process is currently attached to the container.
|
// Determine if the this process is currently attached to the container.
|
||||||
|
@ -98,6 +99,7 @@ func (e *Environment) Events() *events.EventBus {
|
||||||
e.eventMu.Do(func() {
|
e.eventMu.Do(func() {
|
||||||
e.emitter = events.New()
|
e.emitter = events.New()
|
||||||
})
|
})
|
||||||
|
|
||||||
return e.emitter
|
return e.emitter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,12 +176,14 @@ func (e *Environment) Config() *environment.Configuration {
|
||||||
// Sets the stop configuration for the environment.
|
// Sets the stop configuration for the environment.
|
||||||
func (e *Environment) SetStopConfiguration(c api.ProcessStopConfiguration) {
|
func (e *Environment) SetStopConfiguration(c api.ProcessStopConfiguration) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
e.meta.Stop = c
|
e.meta.Stop = c
|
||||||
e.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Environment) SetImage(i string) {
|
func (e *Environment) SetImage(i string) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
e.meta.Image = i
|
e.meta.Image = i
|
||||||
e.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,9 @@ import (
|
||||||
//
|
//
|
||||||
// This process will also confirm that the server environment exists and is in a bootable
|
// This process will also confirm that the server environment exists and is in a bootable
|
||||||
// state. This ensures that unexpected container deletion while Wings is running does
|
// state. This ensures that unexpected container deletion while Wings is running does
|
||||||
// not result in the server becoming unbootable.
|
// not result in the server becoming un-bootable.
|
||||||
func (e *Environment) OnBeforeStart() error {
|
func (e *Environment) OnBeforeStart() error {
|
||||||
// Always destroy and re-create the server container to ensure that synced data from
|
// Always destroy and re-create the server container to ensure that synced data from the Panel is used.
|
||||||
// the Panel is usee.
|
|
||||||
if err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{RemoveVolumes: true}); err != nil {
|
if err := e.client.ContainerRemove(context.Background(), e.Id, types.ContainerRemoveOptions{RemoveVolumes: true}); err != nil {
|
||||||
if !client.IsErrNotFound(err) {
|
if !client.IsErrNotFound(err) {
|
||||||
return errors.WithMessage(err, "failed to remove server docker container during pre-boot")
|
return errors.WithMessage(err, "failed to remove server docker container during pre-boot")
|
||||||
|
@ -49,6 +48,7 @@ func (e *Environment) OnBeforeStart() error {
|
||||||
// call to OnBeforeStart().
|
// call to OnBeforeStart().
|
||||||
func (e *Environment) Start() error {
|
func (e *Environment) Start() error {
|
||||||
sawError := false
|
sawError := false
|
||||||
|
|
||||||
// If sawError is set to true there was an error somewhere in the pipeline that
|
// If sawError is set to true there was an error somewhere in the pipeline that
|
||||||
// got passed up, but we also want to ensure we set the server to be offline at
|
// got passed up, but we also want to ensure we set the server to be offline at
|
||||||
// that point.
|
// that point.
|
||||||
|
@ -235,7 +235,7 @@ func (e *Environment) Terminate(signal os.Signal) error {
|
||||||
|
|
||||||
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
|
sig := strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed")
|
||||||
|
|
||||||
if err := e.client.ContainerKill(context.Background(), e.Id, sig); err != nil {
|
if err := e.client.ContainerKill(context.Background(), e.Id, sig); err != nil && !client.IsErrNotFound(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,9 @@ var ErrNotAttached = errors.New("not attached to instance")
|
||||||
|
|
||||||
func (e *Environment) setStream(s *types.HijackedResponse) {
|
func (e *Environment) setStream(s *types.HijackedResponse) {
|
||||||
e.mu.Lock()
|
e.mu.Lock()
|
||||||
|
defer e.mu.Unlock()
|
||||||
|
|
||||||
e.stream = s
|
e.stream = s
|
||||||
e.mu.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sends the specified command to the stdin of the running container instance. There is no
|
// Sends the specified command to the stdin of the running container instance. There is no
|
||||||
|
@ -71,7 +72,7 @@ func (e *Environment) Readlog(lines int) ([]string, error) {
|
||||||
// Docker stores the logs for server output in a JSON format. This function will iterate over the JSON
|
// Docker stores the logs for server output in a JSON format. This function will iterate over the JSON
|
||||||
// that was read from the log file and parse it into a more human readable format.
|
// that was read from the log file and parse it into a more human readable format.
|
||||||
func (e *Environment) parseLogToStrings(b []byte) ([]string, error) {
|
func (e *Environment) parseLogToStrings(b []byte) ([]string, error) {
|
||||||
var hasError = false
|
hasError := false
|
||||||
var out []string
|
var out []string
|
||||||
|
|
||||||
scanner := bufio.NewScanner(bytes.NewReader(b))
|
scanner := bufio.NewScanner(bytes.NewReader(b))
|
||||||
|
|
|
@ -64,9 +64,11 @@ func (s *Server) StartEventListeners() {
|
||||||
// to terminate again.
|
// to terminate again.
|
||||||
if s.Environment.State() != environment.ProcessStoppingState {
|
if s.Environment.State() != environment.ProcessStoppingState {
|
||||||
s.Environment.SetState(environment.ProcessStoppingState)
|
s.Environment.SetState(environment.ProcessStoppingState)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
s.Log().Warn("stopping server instance, violating throttle limits")
|
s.Log().Warn("stopping server instance, violating throttle limits")
|
||||||
s.PublishConsoleOutputFromDaemon("Your server is being stopped for outputting too much data in a short period of time.")
|
s.PublishConsoleOutputFromDaemon("Your server is being stopped for outputting too much data in a short period of time.")
|
||||||
|
|
||||||
// Completely skip over server power actions and terminate the running instance. This gives the
|
// Completely skip over server power actions and terminate the running instance. This gives the
|
||||||
// server 15 seconds to finish stopping gracefully before it is forcefully terminated.
|
// server 15 seconds to finish stopping gracefully before it is forcefully terminated.
|
||||||
if err := s.Environment.WaitForStop(config.Get().Throttles.StopGracePeriod, true); err != nil {
|
if err := s.Environment.WaitForStop(config.Get().Throttles.StopGracePeriod, true); err != nil {
|
||||||
|
|
|
@ -2,5 +2,5 @@ package system
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// The current version of this software.
|
// The current version of this software.
|
||||||
Version = "0.0.1"
|
Version = "v0.0.1"
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user