Код настройки печатает установщик, появилось удаление панели
Менеджер кладёт код первичной настройки в data/setup-token, установщик
дожидается файла и печатает код последним сообщением — за ним больше не
нужно идти в journalctl. Файл удаляется, как только создан администратор,
и не появляется на уже настроенной панели.
Установщик научился снимать панель с машины: --uninstall убирает службу,
бинарники и правило sudo, --purge вдобавок сносит каталог с мирами,
бэкапами и учётками. Данные удаляются только по явному подтверждению, а
каталог сносится, лишь если похож на установку панели: опечатка в PZ_HOME
не должна стоить чужих файлов. Копия установщика теперь лежит в
/opt/pzmanager, так что удалять можно без похода в репозиторий.
get.sh пробрасывает аргументы установщику и в режиме удаления не качает
бинарник. Заодно исправлена подстановка пустого массива аргументов:
"${ARGS[@]:-}" разворачивается в один пустой аргумент, из-за чего обычная
установка спотыкалась бы о него.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+21
-11
@@ -131,24 +131,34 @@ func serve(cfg *config.Config, users *auth.Store, secureCookies bool) error {
|
||||
// Пока учёток нет, создать первого администратора можно только с этим
|
||||
// кодом — иначе панель захватит любой, кто откроет её первым.
|
||||
setupToken := ""
|
||||
setupTokenFile := filepath.Join(cfg.DataDir, "setup-token")
|
||||
if users.IsEmpty() {
|
||||
setupToken = randomToken()
|
||||
// Код кладём и в файл: установщик читает его оттуда и показывает сразу
|
||||
// после установки, не заставляя идти в журнал.
|
||||
if err := os.WriteFile(setupTokenFile, []byte(setupToken+"\n"), 0o600); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "не удалось записать %s: %v\n", setupTokenFile, err)
|
||||
}
|
||||
fmt.Printf("\n Панель ещё не настроена.\n"+
|
||||
" Откройте её в браузере и введите код первичной настройки:\n\n %s\n\n", setupToken)
|
||||
} else {
|
||||
// Панель уже настроена: файл мог остаться от прошлой установки.
|
||||
os.Remove(setupTokenFile)
|
||||
}
|
||||
|
||||
apiServer := api.New(api.Options{
|
||||
Version: version,
|
||||
Config: cfg,
|
||||
Users: users,
|
||||
Supervisor: supervisor,
|
||||
Jobs: jobs,
|
||||
Backups: backups,
|
||||
Steam: steam,
|
||||
Static: static,
|
||||
SecureCookies: secureCookies,
|
||||
SetupToken: setupToken,
|
||||
Repo: repoURL(),
|
||||
Version: version,
|
||||
Config: cfg,
|
||||
Users: users,
|
||||
Supervisor: supervisor,
|
||||
Jobs: jobs,
|
||||
Backups: backups,
|
||||
Steam: steam,
|
||||
Static: static,
|
||||
SecureCookies: secureCookies,
|
||||
SetupToken: setupToken,
|
||||
SetupTokenFile: setupTokenFile,
|
||||
Repo: repoURL(),
|
||||
})
|
||||
|
||||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
||||
|
||||
Reference in New Issue
Block a user