[#3896cn] Add support for suspending a server and blocking boot when suspended
This commit is contained in:
@@ -215,6 +215,16 @@ func (d *DockerEnvironment) Start() error {
|
||||
}
|
||||
}()
|
||||
|
||||
// If the server is suspended the user shouldn't be able to boot it, in those cases
|
||||
// return a suspension error and let the calling area handle the issue.
|
||||
//
|
||||
// Theoretically you'd have the Panel handle all of this logic, but we cannot do that
|
||||
// because we allow the websocket to control the server power state as well, so we'll
|
||||
// need to handle that action in here.
|
||||
if d.Server.Suspended {
|
||||
return &suspendedError{}
|
||||
}
|
||||
|
||||
c, err := d.Client.ContainerInspect(context.Background(), d.Server.Uuid)
|
||||
if err != nil && !client.IsErrNotFound(err) {
|
||||
return errors.WithStack(err)
|
||||
|
||||
14
server/errors.go
Normal file
14
server/errors.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package server
|
||||
|
||||
type suspendedError struct {
|
||||
}
|
||||
|
||||
func (e *suspendedError) Error() string {
|
||||
return "server is currently in a suspended state"
|
||||
}
|
||||
|
||||
func IsSuspendedError(err error) bool {
|
||||
_, ok := err.(*suspendedError)
|
||||
|
||||
return ok
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"github.com/buger/jsonparser"
|
||||
"github.com/imdario/mergo"
|
||||
"github.com/pkg/errors"
|
||||
"go.uber.org/zap"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Merges data passed through in JSON form into the existing server object.
|
||||
@@ -59,5 +61,41 @@ func (s *Server) UpdateDataStructure(data []byte) error {
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
|
||||
return s.Environment.InSituUpdate()
|
||||
s.runBackgroundActions()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Runs through different actions once a server's configuration has been persisted
|
||||
// to the disk. This function does not return anything as any failures should be logged
|
||||
// but have no effect on actually updating the server itself.
|
||||
//
|
||||
// These tasks run in independent threads where relevant to speed up any updates
|
||||
// that need to happen.
|
||||
func (s *Server) runBackgroundActions() {
|
||||
// Update the environment in place, allowing memory and CPU usage to be adjusted
|
||||
// on the fly without the user needing to reboot (theoretically).
|
||||
go func(server *Server) {
|
||||
if err := server.Environment.InSituUpdate(); err != nil {
|
||||
zap.S().Warnw(
|
||||
"failed to perform in-situ update of server environment",
|
||||
zap.String("server", server.Uuid),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}(s)
|
||||
|
||||
// Check if the server is now suspended, and if so and the process is not terminated
|
||||
// yet, do it immediately.
|
||||
go func(server *Server) {
|
||||
if server.Suspended && server.State != ProcessOfflineState {
|
||||
if err := server.Environment.Terminate(os.Kill); err != nil {
|
||||
zap.S().Warnw(
|
||||
"failed to terminate server environment after seeing suspension",
|
||||
zap.String("server", server.Uuid),
|
||||
zap.Error(err),
|
||||
)
|
||||
}
|
||||
}
|
||||
}(s)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user