feat(admin): manage server updates and local configuration
ci / api / api (push) Successful in 52s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m9s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m35s
release / release (версия и заметки) (push) Successful in 5s
release / android (APK в релиз) (push) Successful in 4m6s
ci / db / db (push) Successful in 1m15s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m19s
ci / ts / ts (packages + web) (push) Successful in 2m34s
release / desktop (Linux и Windows в релиз) (push) Successful in 14m27s
release / prune (старые файлы и прогоны) (push) Successful in 6s
ci / api / api (push) Successful in 52s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 1m9s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m35s
release / release (версия и заметки) (push) Successful in 5s
release / android (APK в релиз) (push) Successful in 4m6s
ci / db / db (push) Successful in 1m15s
ci / docker / docker (образы собираются — их сервер собирает сам при обновлении) (push) Successful in 1m19s
ci / ts / ts (packages + web) (push) Successful in 2m34s
release / desktop (Linux и Windows в релиз) (push) Successful in 14m27s
release / prune (старые файлы и прогоны) (push) Successful in 6s
This commit is contained in:
1 parent
e33abc948c
commit
a29a8b18ad
49 files changed
+3604
-353
No files matched your search
@@ -24,6 +24,7 @@ Pipu Music — self-hosted музыкальный сервис (веб + Android
|
||||
| [i18n.md](i18n.md) | Локализация (ru / en, расширяемость) |
|
||||
| [install-guide.md](install-guide.md) | **Пошагово:** установка сервера на домен с HTTPS, подключение веба и Android |
|
||||
| [admin-guide.md](admin-guide.md) | **Администратору:** пользователи, хранилища, очередь, волна, обновления, диагностика |
|
||||
| [server-management.md](server-management.md) | Управление обновлениями и config.local из админки, установка агента |
|
||||
| [deployment.md](deployment.md) | Справочник по развёртыванию: сервисы, каталоги, переменные |
|
||||
|
||||
## Стек в одном абзаце
|
||||
|
||||
@@ -133,3 +133,8 @@ APK, Linux (`.deb`) и Windows (NSIS) прикладываются к релиз
|
||||
| Сервис перезапускается по кругу | `docker compose logs <сервис>`; часто — закончилось место на диске |
|
||||
|
||||
Остальное — [install-guide.md](install-guide.md#12-если-что-то-не-работает).
|
||||
|
||||
|
||||
## Управление обновлениями и конфигурацией
|
||||
|
||||
Разделы **Обновления** и **Конфигурация** используют агент на хосте. Установка для существующего сервера, права, приоритет `.env` над `config.local` и диагностика описаны в [server-management.md](server-management.md).
|
||||
@@ -97,3 +97,6 @@
|
||||
делает **единственный** параллельный refresh (single-flight) и повторяет запросы.
|
||||
- Роутинг-гарды: `must_change_credentials` → `/setup/admin`; `must_change_password` → `/setup/password`;
|
||||
админские разделы — по `role`.
|
||||
|
||||
|
||||
Управление обновлениями сервера — право `manages_updates`: у admin всегда, другим его выдаёт и отзывает только admin. Оно даёт доступ к `/admin/updates`, управлению источниками и запуску обновления, но не к конфигурации сервера. `/admin/config` доступен только admin. Подробности: [server-management.md](server-management.md).
|
||||
@@ -0,0 +1,127 @@
|
||||
# Управление сервером из веб-интерфейса
|
||||
|
||||
В меню админки доступны **Обновления** (`/admin/updates`) и **Конфигурация**
|
||||
(`/admin/config`). Клиентские APK и desktop-сборки по-прежнему раздаются через
|
||||
существующий механизм `appupdate`; источники обновления сервера от него независимы.
|
||||
|
||||
## Установка на существующий сервер
|
||||
|
||||
После получения версии с управлением сервером выполните на Linux-хосте:
|
||||
|
||||
```bash
|
||||
cd /opt/pipu-music/deploy
|
||||
sudo bash ./install-management.sh
|
||||
./update.sh main # либо тег версии, содержащей эту возможность
|
||||
```
|
||||
|
||||
Новая установка через `sudo ./install.sh` устанавливает агент автоматически.
|
||||
Нужны systemd, Python **3.10+**, Git, Bash, `flock` (util-linux) и Docker Compose
|
||||
**2.24+**. Compose должен поддерживать несколько `--env-file` и тег `!reset`
|
||||
из существующего TLS-overlay. Агент выполняется от root, чтобы запускать Compose
|
||||
и обращаться к данным развёртывания; API продолжает работать без root и без Docker socket.
|
||||
|
||||
Скрипт создаёт `pipu-management.service`, копирует агент вне Git-checkout в
|
||||
`/usr/local/lib/pipu/server-agent.py`, создаёт `deploy/config.local` и общий каталог
|
||||
`${PIPU_DATA}/management` с владельцем UID 65532. Последний монтируется только в API.
|
||||
Приватные настройки источников, состояние, аудит и журналы лежат в
|
||||
`/var/lib/pipu-management`, доступном только root. Нужен доступ этого пользователя
|
||||
к origin; SSH-ключи и known_hosts для приватных репозиториев настройте на хосте.
|
||||
Пароли и токены в URL источников не принимаются.
|
||||
|
||||
После успешного обновления агент автоматически заменяет свою установленную копию
|
||||
из нового checkout и перезапускается, сохранив итоговый статус. Для ручной установки
|
||||
нового кода можно повторно запустить `install-management.sh`.
|
||||
Во время выполняющейся операции не перезапускайте его: systemd остановит дочерние
|
||||
процессы. После прерывания/перезагрузки задача помечается ошибкой, а не успехом.
|
||||
|
||||
## Права
|
||||
|
||||
Администратор всегда может управлять обновлениями. В меню действий пользователя
|
||||
на странице **Пользователи** он может выдать и забрать право **Управление
|
||||
обновлениями** (`manages_updates`). Право действует независимо от роли и проверяется
|
||||
на сервере при каждом запросе. Оно позволяет изменять источники, видеть журнал
|
||||
и запускать обновление. Пользователь с этим правом получает ссылку на обновления,
|
||||
но не получает доступ к пользователям, конфигурации или остальным действиям админа.
|
||||
|
||||
Выдавайте это право доверенным операторам: обновление запускает код выбранного
|
||||
совместимого репозитория на хосте. Только администраторы могут просматривать,
|
||||
сохранять и применять конфигурацию. Выдача/отзыв права записываются в `audit_log`;
|
||||
операции агента с UUID инициатора — в его приватный `audit.jsonl` без значений секретов.
|
||||
|
||||
## Обновления
|
||||
|
||||
При первом обращении автоматически добавляется текущий `git remote origin`.
|
||||
Можно создавать, редактировать и удалять источники; хотя бы один должен остаться.
|
||||
Поддерживаются совместимые Git-репозитории Pipu через HTTP(S) и SSH.
|
||||
|
||||
* **Последний релиз** — значение по умолчанию: максимальный стабильный тег SemVer
|
||||
`vMAJOR.MINOR.PATCH` (также допускается без `v`), без `-rc.N`.
|
||||
* **Выбрать версию** — конкретный релизный тег, включая release candidate.
|
||||
* **main** — текущий commit ветки main.
|
||||
|
||||
Обновления устанавливаются только по нажатию кнопки и после подтверждения.
|
||||
Перед запуском агент повторно читает refs и фиксирует SHA; update.sh проверяет,
|
||||
что полученный commit совпадает. Выбранный источник не перезаписывает origin
|
||||
и не смешивает его теги с тегами другого репозитория. Git checkout с локальными
|
||||
изменениями отклоняется. Защита update.sh от downgrade сохраняется: откат
|
||||
выполняется вручную с `PIPU_ALLOW_DOWNGRADE=1` после проверки совместимости БД.
|
||||
|
||||
Выполнение, ограниченный хвост журнала и итоговый статус доступны на странице.
|
||||
Можно закрыть браузер или переждать перезапуск API: работа продолжается на хосте.
|
||||
Полные логи остаются приватными; для интерфейса известные секреты маскируются.
|
||||
Одновременно агент допускает только одну операцию обновления/применения.
|
||||
Резервная копия и откат схемы БД автоматически не выполняются.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
Реестр поддерживаемых параметров находится в `deploy/config.schema.json`:
|
||||
API, общие параметры сервисов, рекомендатель и развёртывание. Добавляя параметр
|
||||
в конфигурацию сервиса, обновите реестр; для рекомендателя/агента хранилища также
|
||||
проверьте передачу через Compose. Пути томов, сгенерированный DATABASE_URL и
|
||||
некоторые служебные параметры показаны для просмотра и меняются на хосте.
|
||||
Страница не является произвольным редактором nginx/Caddy/YAML-файлов.
|
||||
|
||||
Приоритет при запуске через скрипты:
|
||||
|
||||
1. Явные переменные окружения Compose и значения из `deploy/.env`.
|
||||
2. `deploy/config.local`.
|
||||
3. Встроенные значения по умолчанию.
|
||||
|
||||
Для интерполяции Compose скрипты передают `--env-file config.local --env-file .env`.
|
||||
У API порядок `env_file: [config.local, .env]`; рекомендатель и storage-agent получают
|
||||
только необходимые им переменные через `environment`. При ручном запуске Compose
|
||||
сохраняйте эти флаги, иначе параметры интерполяции из config.local не подхватятся.
|
||||
Страница показывает ожидаемое значение после применения, а не утверждает, что
|
||||
работающий процесс уже перечитал сохранённый файл. Окружение shell запуска Compose
|
||||
тоже может перекрывать интерполяцию; для агента используется окружение systemd.
|
||||
|
||||
В интерфейсе видны локальное значение, значение из `.env` и источник приоритета.
|
||||
Если ключ уже есть в `.env`, изменение его в config.local сохраняется, но не
|
||||
перекрывает `.env` — интерфейс прямо сообщает об этом. Чтобы управлять таким ключом
|
||||
через страницу, удалите его строку из `.env` на хосте. Секреты не возвращаются в API
|
||||
открытым текстом: поле без изменений сохраняет прежний секрет, ввод заменяет,
|
||||
**Сбросить локальное** удаляет только значение из config.local.
|
||||
|
||||
Сохранение атомарно, с правами 0600 и проверкой ревизии: устаревшая форма не затрёт
|
||||
правки другого администратора. Перед сохранением проверяются типы и Compose;
|
||||
при ошибке прежний файл восстанавливается. Произвольные ключи, переводы строк
|
||||
и изменение служебных параметров отклоняются. Сохраняемые значения трактуются
|
||||
буквально: подстановки shell не выполняются.
|
||||
|
||||
Кнопка **Применить и перезапустить** отдельно подтверждает пересоздание контейнеров.
|
||||
Агент запускает `apply-config.sh`, ждёт `/readyz` и сохраняет результат. Если сервисы
|
||||
не стали готовы, состояние — ошибка; исправьте config.local или восстановите его
|
||||
на хосте. Автоматического отката конфигурации после неудачного применения нет.
|
||||
|
||||
Диагностика:
|
||||
|
||||
```bash
|
||||
sudo systemctl status pipu-management.service
|
||||
sudo journalctl -u pipu-management.service -n 100
|
||||
cd /opt/pipu-music/deploy
|
||||
docker compose --env-file config.local --env-file .env logs api
|
||||
```
|
||||
|
||||
Проверки разработки: `python3 -m unittest discover -s deploy -p 'test_*.py'`,
|
||||
`go test ./internal/auth ./internal/management` из `services/api`, а также
|
||||
`pnpm --filter @pipu/web test:e2e e2e/server-management.spec.ts`.
|
||||
Reference in new issue
Block a user