diff --git a/api/server_endpoints.go b/api/server_endpoints.go index 7a4a733..dba7e58 100644 --- a/api/server_endpoints.go +++ b/api/server_endpoints.go @@ -8,10 +8,16 @@ import ( "go.uber.org/zap" ) +const ( + ProcessStopCommand = "command" + ProcessStopSignal = "signal" + ProcessStopNativeStop = "stop" +) + // Defines a single find/replace instance for a given server configuration file. type ConfigurationFileReplacement struct { - Match string `json:"match"` - Value string `json:"value"` + Match string `json:"match"` + Value string `json:"value"` ValueType jsonparser.ValueType `json:"-"` } diff --git a/server/environment_docker.go b/server/environment_docker.go index e3e6eb5..e9a6128 100644 --- a/server/environment_docker.go +++ b/server/environment_docker.go @@ -12,6 +12,7 @@ import ( "github.com/docker/docker/daemon/logger/jsonfilelog" "github.com/docker/go-connections/nat" "github.com/pkg/errors" + "github.com/pterodactyl/wings/api" "go.uber.org/zap" "golang.org/x/net/context" "io" @@ -134,7 +135,7 @@ func (d *DockerEnvironment) Start() error { // 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 // that point. - defer func () { + defer func() { if sawError { d.Server.SetState(ProcessOfflineState) } @@ -191,9 +192,18 @@ func (d *DockerEnvironment) Start() error { // Stops the container that the server is running in. This will allow up to 10 // seconds to pass before a failure occurs. func (d *DockerEnvironment) Stop() error { - t := time.Second * 10 + stop := d.Server.processConfiguration.Stop + if stop.Type == api.ProcessStopSignal { + return d.Terminate(os.Kill) + } d.Server.SetState(ProcessStoppingState) + if stop.Type == api.ProcessStopCommand { + return d.SendCommand(stop.Value) + } + + t := time.Second * 10 + return d.Client.ContainerStop(context.Background(), d.Server.Uuid, &t) } @@ -211,7 +221,10 @@ func (d *DockerEnvironment) Terminate(signal os.Signal) error { } d.Server.SetState(ProcessStoppingState) - return d.Client.ContainerKill(ctx, d.Server.Uuid, "SIGKILL") + + return d.Client.ContainerKill( + ctx, d.Server.Uuid, strings.TrimPrefix("signal ", signal.String()), + ) } // Attaches to the docker container itself and ensures that we can pipe data in and out diff --git a/server/server.go b/server/server.go index f9f8c2d..9f21fe3 100644 --- a/server/server.go +++ b/server/server.go @@ -218,7 +218,11 @@ func FromConfiguration(data []byte, cfg *config.SystemConfiguration) (*Server, e // This is also done when the server is booted, however we need to account for instances // where the server is already running and the Daemon reboots. In those cases this will // allow us to you know, stop servers. - s.GetProcessConfiguration() + if cfg, err := s.GetProcessConfiguration(); err != nil { + return nil, err + } else { + s.processConfiguration = cfg + } return s, nil }