Fix servers getting marked as Stopping when they should be Offline

This commit is contained in:
Matthew Penner 2020-08-04 17:19:13 -06:00
parent 9ec323350e
commit 234fbfa8ec
3 changed files with 32 additions and 18 deletions

View File

@ -201,8 +201,8 @@ func (d *DockerEnvironment) 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...
d.Server.SetState(ProcessStoppingState) _ = d.Server.SetState(ProcessStoppingState)
d.Server.SetState(ProcessOfflineState) _ = d.Server.SetState(ProcessOfflineState)
} }
}() }()
@ -228,7 +228,7 @@ func (d *DockerEnvironment) 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 {
d.Server.SetState(ProcessRunningState) _ = d.Server.SetState(ProcessRunningState)
return d.Attach() return d.Attach()
} }
@ -243,7 +243,8 @@ func (d *DockerEnvironment) Start() error {
} }
} }
d.Server.SetState(ProcessStartingState) _ = d.Server.SetState(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.
sawError = true sawError = true
@ -289,7 +290,8 @@ func (d *DockerEnvironment) Stop() error {
return d.Terminate(os.Kill) return d.Terminate(os.Kill)
} }
d.Server.SetState(ProcessStoppingState) _ = d.Server.SetState(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
// the instance. If we are not for some reason, just send the container stop event. // the instance. If we are not for some reason, just send the container stop event.
if d.IsAttached() && stop.Type == api.ProcessStopCommand { if d.IsAttached() && stop.Type == api.ProcessStopCommand {
@ -304,7 +306,7 @@ func (d *DockerEnvironment) Stop() error {
// an error. // an error.
if client.IsErrNotFound(err) { if client.IsErrNotFound(err) {
d.SetStream(nil) d.SetStream(nil)
d.Server.SetState(ProcessOfflineState) _ = d.Server.SetState(ProcessOfflineState)
return nil return nil
} }
@ -333,8 +335,10 @@ func (d *DockerEnvironment) Restart() error {
// will be terminated forcefully depending on the value of the second argument. // will be terminated forcefully depending on the value of the second argument.
func (d *DockerEnvironment) WaitForStop(seconds int, terminate bool) error { func (d *DockerEnvironment) WaitForStop(seconds int, terminate bool) error {
if d.Server.GetState() == ProcessOfflineState { if d.Server.GetState() == ProcessOfflineState {
log.WithField("server", d.Server.Id()).Debug("server is already offline, not waiting for stop.")
return nil return nil
} }
log.WithField("server", d.Server.Id()).Debug("waiting for server to stop")
if err := d.Stop(); err != nil { if err := d.Stop(); err != nil {
return errors.WithStack(err) return errors.WithStack(err)
@ -377,7 +381,9 @@ func (d *DockerEnvironment) Terminate(signal os.Signal) error {
return nil return nil
} }
d.Server.SetState(ProcessStoppingState) // We set it to stopping than offline to prevent crash detection from being triggered.
_ = d.Server.SetState(ProcessStoppingState)
_ = d.Server.SetState(ProcessOfflineState)
return d.Client.ContainerKill( return d.Client.ContainerKill(
context.Background(), d.Server.Id(), strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed"), context.Background(), d.Server.Id(), strings.TrimSuffix(strings.TrimPrefix(signal.String(), "signal "), "ed"),
@ -387,8 +393,9 @@ func (d *DockerEnvironment) Terminate(signal os.Signal) error {
// Remove the Docker container from the machine. If the container is currently running // Remove the Docker container from the machine. If the container is currently running
// it will be forcibly stopped by Docker. // it will be forcibly stopped by Docker.
func (d *DockerEnvironment) Destroy() error { func (d *DockerEnvironment) Destroy() error {
// Avoid crash detection firing off. // We set it to stopping than offline to prevent crash detection from being triggered.
d.Server.SetState(ProcessStoppingState) _ = d.Server.SetState(ProcessStoppingState)
_ = d.Server.SetState(ProcessOfflineState)
err := d.Client.ContainerRemove(context.Background(), d.Server.Id(), types.ContainerRemoveOptions{ err := d.Client.ContainerRemove(context.Background(), d.Server.Id(), types.ContainerRemoveOptions{
RemoveVolumes: true, RemoveVolumes: true,
@ -471,11 +478,11 @@ func (d *DockerEnvironment) Attach() error {
go func() { go func() {
defer d.stream.Close() defer d.stream.Close()
defer func() { defer func() {
d.Server.SetState(ProcessOfflineState) _ = d.Server.SetState(ProcessOfflineState)
d.SetStream(nil) d.SetStream(nil)
}() }()
io.Copy(console, d.stream.Reader) _, _ = io.Copy(console, d.stream.Reader)
}() }()
return nil return nil
@ -542,14 +549,14 @@ func (d *DockerEnvironment) EnableResourcePolling() error {
d.Server.Log().WithField("error", err).Warn("encountered error processing server stats, stopping collection") d.Server.Log().WithField("error", err).Warn("encountered error processing server stats, stopping collection")
} }
d.DisableResourcePolling() _ = d.DisableResourcePolling()
return return
} }
// Disable collection if the server is in an offline state and this process is // Disable collection if the server is in an offline state and this process is
// still running. // still running.
if s.GetState() == ProcessOfflineState { if s.GetState() == ProcessOfflineState {
d.DisableResourcePolling() _ = d.DisableResourcePolling()
return return
} }
@ -613,7 +620,7 @@ func (d *DockerEnvironment) ensureImageExists() error {
continue continue
} }
log.WithField("registry", registry).Debug("using authentication for repository") log.WithField("registry", registry).Debug("using authentication for registry")
registryAuth = &c registryAuth = &c
break break
} }
@ -733,7 +740,7 @@ func (d *DockerEnvironment) Create() error {
d.Server.Log().WithFields(log.Fields{ d.Server.Log().WithFields(log.Fields{
"source_path": m.Source, "source_path": m.Source,
"target_path": m.Target, "target_path": m.Target,
"read_only": m.ReadOnly, "read_only": m.ReadOnly,
}).Debug("attaching custom server mount point to container") }).Debug("attaching custom server mount point to container")
} }
} }

View File

@ -55,6 +55,12 @@ func (s *Server) Install(sync bool) error {
l.Warn("failed to notify panel of server install state") l.Warn("failed to notify panel of server install state")
} }
// 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)
// 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.
s.Events().Publish(InstallCompletedEvent, "") s.Events().Publish(InstallCompletedEvent, "")

View File

@ -31,11 +31,11 @@ func (s *Server) onConsoleOutput(data string) {
if s.GetState() == ProcessStartingState && strings.Contains(data, match) { if s.GetState() == ProcessStartingState && strings.Contains(data, match) {
s.Log().WithFields(log.Fields{ s.Log().WithFields(log.Fields{
"match": match, "match": match,
"against": data, "against": data,
}).Debug("detected server in running state based on console line output") }).Debug("detected server in running state based on console line output")
s.SetState(ProcessRunningState) _ = s.SetState(ProcessRunningState)
} }
// If the command sent to the server is one that should stop the server we will need to // If the command sent to the server is one that should stop the server we will need to
@ -43,8 +43,9 @@ func (s *Server) onConsoleOutput(data string) {
// cause the server to unexpectedly restart on the user. // cause the server to unexpectedly restart on the user.
if s.IsRunning() { if s.IsRunning() {
stop := s.ProcessConfiguration().Stop stop := s.ProcessConfiguration().Stop
if stop.Type == api.ProcessStopCommand && data == stop.Value { if stop.Type == api.ProcessStopCommand && data == stop.Value {
s.SetState(ProcessStoppingState) _ = s.SetState(ProcessStoppingState)
} }
} }
} }