Обновление панели из интерфейса и режим обновления в установщике
CI / test (push) Successful in 21s
Release / release (push) Successful in 27s

Установщик стал идемпотентным: на уже настроенной машине он определяет
установленную версию, останавливает службу, меняет бинарник и поднимает её
обратно, не трогая конфиг, миры и учётные записи. Зависимости при
обновлении не переустанавливаются — это лишние минуты apt.

Кнопки «Обновить» и «Перезапустить панель» появились на вкладке
«Настройки» вместе с текущей версией и описанием нового релиза.

Панель работает от непривилегированного пользователя и не может ни
заменить свой бинарник в /usr/local/bin, ни дёрнуть systemctl. Вместо
того чтобы расширять её права, установщик кладёт root-скрипт
pzmanager-admin и разрешает сервисному пользователю через sudoers ровно
эту одну команду. Скрипт сверяет sha256 скачанного бинарника с
checksums.txt релиза. Если правила sudo нет, кнопки не будет — панель
покажет команду для терминала.

Перед обновлением и перезапуском игровой сервер останавливается штатным
quit: иначе его погасил бы systemd уже в момент рестарта, и ожидание
растянулось бы на таймаут остановки.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-04 19:37:53 +03:00
co-authored by Claude Opus 5
parent 49d549463a
commit c0797be745
13 changed files with 833 additions and 25 deletions
+13
View File
@@ -29,6 +29,10 @@ import (
"github.com/mrleo1nid/pzmanager/web"
)
// defaultRepo — откуда панель узнаёт о новых версиях. Меняется переменной
// окружения PZMANAGER_REPO, если репозиторий переехал или это форк.
const defaultRepo = "https://gitea.hsrv.site/mrleo1nid/pzmanager"
// version подставляется при сборке: -ldflags "-X main.version=v1.2.3".
// В сборке из рабочей копии остаётся "dev".
var version = "dev"
@@ -144,6 +148,7 @@ func serve(cfg *config.Config, users *auth.Store, secureCookies bool) error {
Static: static,
SecureCookies: secureCookies,
SetupToken: setupToken,
Repo: repoURL(),
})
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
@@ -274,6 +279,14 @@ func readPassword(prompt string) (string, error) {
return string(raw), nil
}
// repoURL возвращает адрес репозитория для проверки обновлений.
func repoURL() string {
if env := os.Getenv("PZMANAGER_REPO"); env != "" {
return env
}
return defaultRepo
}
func randomToken() string {
buf := make([]byte, 12)
if _, err := rand.Read(buf); err != nil {