Менеджер запускает сервер PZ как дочерний процесс и держит его stdin/stdout: отсюда живая консоль без RCON, стриминг логов через SSE и корректная остановка по цепочке quit -> SIGTERM -> SIGKILL для всей группы процессов. Сам менеджер работает под systemd. Что входит: - управление жизненным циклом сервера, автозапуск и автоподъём после падения; - метрики процесса из /proc и состояние хоста, список игроков онлайн; - редакторы servertest.ini и SandboxVars.lua, сохраняющие исходное форматирование файлов; - моды: списки Workshop ID и Mod ID с порядком загрузки, названия из Steam; - бэкапы мира по расписанию и вручную, с ротацией и восстановлением; - установка и обновление сервера через SteamCMD; - вход по логину и паролю, первичная настройка по одноразовому коду. Веб-интерфейс без сборщика, вшит в бинарник через embed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
34 lines
877 B
Go
34 lines
877 B
Go
//go:build !windows
|
|
|
|
package pzserver
|
|
|
|
import (
|
|
"os/exec"
|
|
"syscall"
|
|
)
|
|
|
|
// setProcessGroup просит ядро выделить процессу собственную группу: сервер PZ
|
|
// это скрипт-обёртка, порождающая JVM, и убивать их нужно вместе.
|
|
func setProcessGroup(cmd *exec.Cmd) {
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid: true}
|
|
}
|
|
|
|
// processGroupID возвращает pgid запущенного процесса.
|
|
func processGroupID(pid int) int {
|
|
pgid, err := syscall.Getpgid(pid)
|
|
if err != nil {
|
|
return pid
|
|
}
|
|
return pgid
|
|
}
|
|
|
|
// signalGroup шлёт сигнал всей группе (отрицательный pid = группа).
|
|
func signalGroup(pgid int, sig syscall.Signal) error {
|
|
return syscall.Kill(-pgid, sig)
|
|
}
|
|
|
|
var (
|
|
sigTerm = syscall.SIGTERM
|
|
sigKill = syscall.SIGKILL
|
|
)
|