2019-11-24 23:08:38 +00:00
|
|
|
package server
|
|
|
|
|
|
|
|
import (
|
2022-02-01 00:09:08 +00:00
|
|
|
"time"
|
|
|
|
|
2021-08-29 20:37:18 +00:00
|
|
|
"github.com/pterodactyl/wings/environment/docker"
|
2021-08-02 21:07:00 +00:00
|
|
|
|
2020-08-20 01:58:48 +00:00
|
|
|
"github.com/pterodactyl/wings/environment"
|
2019-11-24 23:08:38 +00:00
|
|
|
)
|
|
|
|
|
2021-08-29 20:37:18 +00:00
|
|
|
// SyncWithEnvironment updates the environment for the server to match any of
|
|
|
|
// the changed data. This pushes new settings and environment variables to the
|
|
|
|
// environment. In addition, the in-situ update method is called on the
|
|
|
|
// environment which will allow environments that make use of it (such as Docker)
|
|
|
|
// to immediately apply some settings without having to wait on a server to
|
|
|
|
// restart.
|
2019-11-30 23:19:08 +00:00
|
|
|
//
|
2021-08-29 20:37:18 +00:00
|
|
|
// This functionality allows a server's resources limits to be modified on the
|
|
|
|
// fly and have them apply right away allowing for dynamic resource allocation
|
|
|
|
// and responses to abusive server processes.
|
2020-08-28 04:08:33 +00:00
|
|
|
func (s *Server) SyncWithEnvironment() {
|
|
|
|
s.Log().Debug("syncing server settings with environment")
|
|
|
|
|
2021-08-29 20:37:18 +00:00
|
|
|
cfg := s.Config()
|
|
|
|
|
2020-08-28 04:08:33 +00:00
|
|
|
// Update the environment settings using the new information from this server.
|
|
|
|
s.Environment.Config().SetSettings(environment.Settings{
|
|
|
|
Mounts: s.Mounts(),
|
2021-08-29 20:37:18 +00:00
|
|
|
Allocations: cfg.Allocations,
|
|
|
|
Limits: cfg.Build,
|
2020-08-28 04:08:33 +00:00
|
|
|
})
|
|
|
|
|
2021-08-29 20:37:18 +00:00
|
|
|
// For Docker specific environments we also want to update the configured image
|
|
|
|
// and stop configuration.
|
|
|
|
if e, ok := s.Environment.(*docker.Environment); ok {
|
|
|
|
s.Log().Debug("syncing stop configuration with configured docker environment")
|
|
|
|
e.SetImage(cfg.Container.Image)
|
|
|
|
e.SetStopConfiguration(s.ProcessConfiguration().Stop)
|
|
|
|
}
|
|
|
|
|
2020-08-28 04:08:33 +00:00
|
|
|
// If build limits are changed, environment variables also change. Plus, any modifications to
|
|
|
|
// the startup command also need to be properly propagated to this environment.
|
|
|
|
//
|
|
|
|
// @see https://github.com/pterodactyl/panel/issues/2255
|
|
|
|
s.Environment.Config().SetEnvironmentVariables(s.GetEnvironmentVariables())
|
2020-07-19 23:27:55 +00:00
|
|
|
|
|
|
|
if !s.IsSuspended() {
|
|
|
|
// Update the environment in place, allowing memory and CPU usage to be adjusted
|
|
|
|
// on the fly without the user needing to reboot (theoretically).
|
|
|
|
s.Log().Info("performing server limit modification on-the-fly")
|
|
|
|
if err := s.Environment.InSituUpdate(); err != nil {
|
2020-08-28 04:08:33 +00:00
|
|
|
// This is not a failure, the process is still running fine and will fix itself on the
|
|
|
|
// next boot, or fail out entirely in a more logical position.
|
2020-07-19 23:27:55 +00:00
|
|
|
s.Log().WithField("error", err).Warn("failed to perform on-the-fly update of the server environment")
|
|
|
|
}
|
2020-08-28 04:08:33 +00:00
|
|
|
} else {
|
|
|
|
// Checks if the server is now in a suspended state. If so and a server process is currently running it
|
|
|
|
// will be gracefully stopped (and terminated if it refuses to stop).
|
2020-11-20 21:35:29 +00:00
|
|
|
if s.Environment.State() != environment.ProcessOfflineState {
|
2020-09-11 03:16:16 +00:00
|
|
|
s.Log().Info("server suspended with running process state, terminating now")
|
|
|
|
|
|
|
|
go func(s *Server) {
|
2022-02-01 00:09:08 +00:00
|
|
|
if err := s.Environment.WaitForStop(s.Context(), time.Minute, true); err != nil {
|
2020-09-11 03:16:16 +00:00
|
|
|
s.Log().WithField("error", err).Warn("failed to terminate server environment after suspension")
|
|
|
|
}
|
|
|
|
}(s)
|
|
|
|
}
|
2020-07-19 23:27:55 +00:00
|
|
|
}
|
2019-11-25 04:54:03 +00:00
|
|
|
}
|