Cleanup server sync logic to work in a single consistent format (#101)

* Cleanup server sync logic to work in a single consistent format

Previously we had a mess of a function trying to update server details from a patch request. This change just centralizes everything to a single Sync() call when a server needs to update itself.

We can also eventually update the panel (in V2) to not hit the patch endpoint, rather it can just be a generic endpoint that is hit after a server is updated on the Panel that tells Wings to re-sync the data to get the environment changes on the fly.

The changes I made to the patch function currently act like that, with a slightly fragile 2 second wait to let the panel persist the changes since I don't want this to be a breaking change on that end.

* Remove legacy server patch endpoint; replace with simpler sync endpoint
This commit is contained in:
Dane Everitt
2021-08-29 13:37:18 -07:00
committed by GitHub
parent d4a8f25cc6
commit 5764894a5e
5 changed files with 73 additions and 171 deletions

View File

@@ -2,6 +2,7 @@ package server
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
@@ -15,7 +16,6 @@ import (
"github.com/pterodactyl/wings/config"
"github.com/pterodactyl/wings/environment"
"github.com/pterodactyl/wings/environment/docker"
"github.com/pterodactyl/wings/events"
"github.com/pterodactyl/wings/remote"
"github.com/pterodactyl/wings/server/filesystem"
@@ -167,31 +167,48 @@ func (s *Server) Sync() error {
}
return errors.WithStackIf(err)
}
return s.SyncWithConfiguration(cfg)
if err := s.SyncWithConfiguration(cfg); err != nil {
return errors.WithStackIf(err)
}
// Update the disk space limits for the server whenever the configuration for
// it changes.
s.fs.SetDiskLimit(s.DiskSpace())
s.SyncWithEnvironment()
return nil
}
// SyncWithConfiguration accepts a configuration object for a server and will
// sync all of the values with the existing server state. This only replaces the
// existing configuration and process configuration for the server. The
// underlying environment will not be affected. This is because this function
// can be called from scoped where the server may not be fully initialized,
// therefore other things like the filesystem and environment may not exist yet.
func (s *Server) SyncWithConfiguration(cfg remote.ServerConfigurationResponse) error {
// Update the data structure and persist it to the disk.
if err := s.UpdateDataStructure(cfg.Settings); err != nil {
return err
c := Configuration{}
if err := json.Unmarshal(cfg.Settings, &c); err != nil {
return errors.WithStackIf(err)
}
s.cfg.mu.Lock()
defer s.cfg.mu.Unlock()
// Lock the new configuration. Since we have the defered Unlock above we need
// to make sure that the NEW configuration object is already locked since that
// defer is running on the memory address for "s.cfg.mu" which we're explcitly
// changing on the next line.
c.mu.Lock()
//goland:noinspection GoVetCopyLock
s.cfg = c
s.Lock()
s.procConfig = cfg.ProcessConfiguration
s.Unlock()
// Update the disk space limits for the server whenever the configuration
// for it changes.
s.fs.SetDiskLimit(s.DiskSpace())
// If this is a Docker environment we need to sync the stop configuration with it so that
// the process isn't just terminated when a user requests it be stopped.
if e, ok := s.Environment.(*docker.Environment); ok {
s.Log().Debug("syncing stop configuration with configured docker environment")
e.SetImage(s.Config().Container.Image)
e.SetStopConfiguration(cfg.ProcessConfiguration.Stop)
}
return nil
}