feat: add signal-bound server supervisor command

This commit is contained in:
Josh Creek
2026-09-01 09:19:25 +01:00
parent 58508bd87c
commit 4d83ec1525
3 changed files with 85 additions and 1 deletions
+71
View File
@@ -0,0 +1,71 @@
package main
import (
"context"
"flag"
"fmt"
"os"
"os/signal"
"syscall"
"time"
"github.com/cosmic-clash/cosmic-clash/server/supervisor"
)
const usageText = `Usage: game-server-supervisor [options] -- <game-server-command> [args...]
The child command is started only after an allocated Agones endpoint has been
validated and, when configured, an explicit process-ready probe succeeds.
SIGTERM/SIGINT requests authenticated drain before the bounded grace deadline.
`
func main() {
args := os.Args[1:]
separator := -1
for i, arg := range args {
if arg == "--" {
separator = i
break
}
}
if separator < 0 || separator == len(args)-1 {
fmt.Fprint(os.Stderr, usageText)
os.Exit(2)
}
options := flag.NewFlagSet("game-server-supervisor", flag.ContinueOnError)
options.SetOutput(os.Stderr)
sdkBaseURL := options.String("sdk-base-url", "", "Agones SDK REST base URL; empty enables direct mode")
readyURL := options.String("ready-url", "", "explicit process-ready probe URL")
drainURL := options.String("drain-url", "", "loopback drain URL")
drainTokenEnv := options.String("drain-token-env", "COSMIC_CLASH_DRAIN_TOKEN", "environment variable containing the drain bearer token")
transport := options.String("transport", "enet", "enet or steam_sdr")
grace := options.Duration("drain-grace", supervisor.DefaultDrainGrace, "maximum graceful drain duration")
if err := options.Parse(args[:separator]); err != nil {
os.Exit(2)
}
token := ""
if *drainTokenEnv != "" {
token = os.Getenv(*drainTokenEnv)
}
s, err := supervisor.New(supervisor.Config{
Command: args[separator+1:],
SDKBaseURL: *sdkBaseURL,
ReadyURL: *readyURL,
DrainURL: *drainURL,
DrainToken: token,
Transport: *transport,
ReadyTimeout: 30 * time.Second,
})
if err != nil {
fmt.Fprintf(os.Stderr, "game-server-supervisor: %v\n", err)
os.Exit(2)
}
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
if err := s.Run(ctx, *grace); err != nil {
fmt.Fprintf(os.Stderr, "game-server-supervisor: %v\n", err)
os.Exit(1)
}
}