docs: clean-install-only, versions.env и очистка предыдущего поколения
Новый docs/14-legacy-cleanup.md: как выглядит отказ установщика, полный список маркеров чужой установки, что сохранить перед очисткой, работа purge-v0.sh, ручная процедура и отдельно - случай незавершённой установки текущего поколения, где нужен repair, а не очистка. Обновлено под фактическое поведение: - README и package/docs: установка описана как две фазы, PHASE 0 ничего не меняет; добавлен troubleshooting по отказу clean-host; версии toolchain больше не передаются через окружение; - 02-build-layer: раздел про versions.env (что в нём есть и чего нет и почему), verify_versions_contract, проверка происхождения артефакта по upstream hashes.txt; - 08-orchestrator-spec: двухфазный контракт, read-only guard, идентификация поколения в install-state, ownership-aware rollback, расширенная семантическая проверка конфига, структурная редакция; - 04-admin-panel: таблица удалённых маршрутов и почему они удалены, а не оставлены заглушками; сужена формулировка гарантии санитайза; - 11-testing: новые unit-наборы, полный список инвариантов конфига, раздел про одну реализацию URI вместо двух, сценарий проверки границы установки на живом сервере; - 12-operations и 13-runbook: диагностика отказов по поколению, поведение diagnostics-бандла; - tools/build/README: контракт версий, обе суммы Bun, hashes.txt. CHANGELOG: раздел Unreleased с разбором каждого исправленного дефекта.
This commit is contained in:
@@ -0,0 +1,221 @@
|
||||
# Очистка сервера от предыдущей установки
|
||||
|
||||
## Зачем этот документ
|
||||
|
||||
HY2XS v1 **не поддерживает установку поверх** и **не мигрирует состояние 0.x**.
|
||||
Это осознанное решение продукта, а не временное ограничение: попытка угадать,
|
||||
как устроен произвольный старый сервер, приводит к полурабочим установкам,
|
||||
которые невозможно диагностировать.
|
||||
|
||||
Отсюда следует жёсткий системный инвариант:
|
||||
|
||||
```text
|
||||
обнаружена старая установка
|
||||
↓
|
||||
НОЛЬ изменений на сервере
|
||||
↓
|
||||
понятный отказ
|
||||
↓
|
||||
явная очистка (этот документ)
|
||||
↓
|
||||
установка HY2XS v1 с нуля
|
||||
```
|
||||
|
||||
Установщик **никогда** не выполняет очистку самостоятельно. Удаление чужого
|
||||
состояния — операция оператора, а не побочный эффект запуска `install.sh`.
|
||||
|
||||
## Как выглядит отказ
|
||||
|
||||
Установщик проверяет чистоту хоста в **PHASE 0** — до того, как изменит хотя бы
|
||||
один persistent path, включая `/usr/local/lib/hy2xs`:
|
||||
|
||||
```text
|
||||
[hy2xs-install] PHASE 0: read-only checks (no persistent path is modified)
|
||||
[hy2xs-install] verifying package checksums
|
||||
[hy2xs-install] running clean-host preflight from the unpacked package
|
||||
[hy2xs] ERROR: На сервере обнаружена предыдущая или посторонняя установка.
|
||||
HY2XS v1 не поддерживает установку поверх и не мигрирует состояние 0.x.
|
||||
Ни один файл на сервере не изменён.
|
||||
|
||||
Найденные маркеры:
|
||||
- /etc/hysteria/post-install.env (post-install.env предыдущей установки HY2XS)
|
||||
- hy2xs-admin.service (systemd-юнит админки HY2XS)
|
||||
|
||||
Очистите сервер и установите HY2XS заново: см. docs/14-legacy-cleanup.md
|
||||
```
|
||||
|
||||
Если вы видите этот текст — сервер в том же состоянии, в котором был до запуска.
|
||||
|
||||
Отдельный случай — конфигурация без маркера схемы:
|
||||
|
||||
```text
|
||||
HY2XS_CONFIG_SCHEMA_VERSION отсутствует в конфигурации.
|
||||
Похоже на конфигурацию предыдущего поколения (0.x) или на неизвестный формат.
|
||||
```
|
||||
|
||||
До v1 поля `HY2XS_CONFIG_SCHEMA_VERSION` не существовало, поэтому его отсутствие
|
||||
трактуется как legacy, а не как «текущая схема по умолчанию».
|
||||
|
||||
## Что именно проверяется
|
||||
|
||||
Контракт чистого хоста объявлен в `orchestrator/src/steps/cleanHost.ts` и покрыт
|
||||
тестами. Установка отказывается, если найден хотя бы один из объектов:
|
||||
|
||||
| Объект | Что это |
|
||||
| --- | --- |
|
||||
| `/etc/hysteria/post-install.env` | post-install.env предыдущей установки |
|
||||
| `/etc/hy2xs/hy2xs.env` | runtime-конфигурация предыдущей установки |
|
||||
| `/etc/hy2xs/bootstrap-admin.secret` | bootstrap-секрет администратора |
|
||||
| `/var/lib/hy2xs/install-state.json` | маркер состояния установки |
|
||||
| `/usr/local/lib/hy2xs/package` | runtime-пакет предыдущей установки |
|
||||
| `/etc/hysteria/config.yaml` | сгенерированный серверный конфиг |
|
||||
| `/usr/local/bin/hysteria` | уже установленный бинарник Hysteria |
|
||||
| `/etc/nftables.d/hy2xs.nft` | nftables-фрагмент HY2XS |
|
||||
| `hy2xs-admin.service` | systemd-юнит админки |
|
||||
| `hysteria-server.service` | systemd-юнит сервера Hysteria |
|
||||
| `h-ui.service`, `/usr/local/h-ui` | наследие панели поколения 0.x |
|
||||
| `HY2XS_INSTALL_DIR` (по умолчанию `/opt/hy2xs-admin`) | каталог приложения |
|
||||
| `HY2XS_DATA_DIR` (по умолчанию `/var/lib/hy2xs-admin`) | каталог данных и БД |
|
||||
|
||||
Последние два пути берутся из конфигурации, а не захардкожены: нестандартная
|
||||
установка тоже должна быть обнаружена.
|
||||
|
||||
## Перед очисткой
|
||||
|
||||
Очистка **разрушительная**. Она удаляет базу админки вместе с учётными записями
|
||||
пиров: выданные пользователям ссылки перестанут работать.
|
||||
|
||||
Сохраните то, что вам нужно:
|
||||
|
||||
```bash
|
||||
# ссылки и учётные записи пиров (если старая панель ещё работает)
|
||||
sudo sqlite3 /var/lib/hy2xs-admin/h_ui.db '.dump' > ~/hy2xs-peers-dump.sql
|
||||
|
||||
# серверный конфиг Hysteria
|
||||
sudo cp -a /etc/hysteria/config.yaml ~/hysteria-config.yaml.bak
|
||||
|
||||
# post-install-справка предыдущей установки
|
||||
sudo cp -a /etc/hysteria/post-install.env ~/post-install.env.bak
|
||||
```
|
||||
|
||||
Файлы содержат секреты. Снимите с них лишние права и не пересылайте как есть:
|
||||
|
||||
```bash
|
||||
chmod 600 ~/hy2xs-peers-dump.sql ~/hysteria-config.yaml.bak ~/post-install.env.bak
|
||||
```
|
||||
|
||||
Для безопасной передачи конфига наружу используйте редактирование секретов:
|
||||
|
||||
```bash
|
||||
hy2xs-orchestrator redact-config --config ~/hysteria-config.yaml.bak --out ~/hysteria-config.redacted.yaml
|
||||
```
|
||||
|
||||
## Очистка скриптом
|
||||
|
||||
Скрипт `tools/legacy/purge-v0.sh` лежит в репозитории. Скопируйте его на сервер.
|
||||
|
||||
Сначала — план. Без флагов скрипт **ничего не меняет**:
|
||||
|
||||
```bash
|
||||
sudo ./purge-v0.sh
|
||||
```
|
||||
|
||||
Он покажет, какие службы будут остановлены, какие пути удалены и какие из них
|
||||
существуют прямо сейчас.
|
||||
|
||||
Затем — выполнение. Требуются оба флага, `--apply` без подтверждения не работает:
|
||||
|
||||
```bash
|
||||
sudo ./purge-v0.sh --apply --yes-i-know
|
||||
```
|
||||
|
||||
Если бинарник Hysteria нужно оставить (например, вы проверяете им что-то ещё):
|
||||
|
||||
```bash
|
||||
sudo ./purge-v0.sh --apply --yes-i-know --keep-hysteria-binary
|
||||
```
|
||||
|
||||
В конце скрипт сам проверяет, что хост стал чистым по тому же контракту, который
|
||||
применяет установщик. Если что-то осталось, он назовёт конкретные объекты и
|
||||
завершится с ошибкой.
|
||||
|
||||
## Что скрипт делает и чего не делает
|
||||
|
||||
Делает:
|
||||
|
||||
1. останавливает и выключает `hysteria-server`, `hy2xs-admin`, `h-ui`;
|
||||
2. снимает таймеры отката firewall `hy2xs-fw-rollback-*` — они переживают
|
||||
неудачную установку и иначе продолжили бы менять ruleset уже после очистки;
|
||||
3. удаляет unit-файлы и выполняет `daemon-reload`;
|
||||
4. удаляет каталоги приложения, конфигурации, данных и логов;
|
||||
5. удаляет фрагмент `/etc/nftables.d/hy2xs.nft` и строку `include` для него из
|
||||
`/etc/nftables.conf`, после чего перезагружает ruleset;
|
||||
6. проверяет чистоту хоста.
|
||||
|
||||
Не делает:
|
||||
|
||||
- не трогает `sshd` и его конфигурацию;
|
||||
- не удаляет `/etc/nftables.conf` целиком — остальной ruleset принадлежит
|
||||
оператору;
|
||||
- не удаляет системные пакеты, установленные ранее;
|
||||
- не запускается автоматически из установщика.
|
||||
|
||||
## Ручная очистка
|
||||
|
||||
Если запускать скрипт нежелательно, те же шаги вручную:
|
||||
|
||||
```bash
|
||||
sudo systemctl stop hysteria-server hy2xs-admin h-ui
|
||||
sudo systemctl disable hysteria-server hy2xs-admin h-ui
|
||||
sudo systemctl reset-failed hysteria-server hy2xs-admin h-ui
|
||||
|
||||
# таймеры отката firewall от незавершённой установки
|
||||
sudo systemctl list-units --all 'hy2xs-fw-rollback-*'
|
||||
# для каждого найденного юнита:
|
||||
# sudo systemctl stop <unit> && sudo systemctl disable <unit>
|
||||
# sudo rm -f /etc/systemd/system/<unit>
|
||||
|
||||
sudo rm -f /etc/systemd/system/hysteria-server.service \
|
||||
/etc/systemd/system/hy2xs-admin.service \
|
||||
/etc/systemd/system/h-ui.service
|
||||
sudo systemctl daemon-reload
|
||||
|
||||
sudo rm -rf /etc/hy2xs /etc/hysteria /var/lib/hy2xs /var/lib/hy2xs-admin \
|
||||
/var/lib/hysteria /var/log/hy2xs /opt/hy2xs-admin \
|
||||
/usr/local/lib/hy2xs /usr/local/h-ui
|
||||
sudo rm -f /usr/local/bin/hysteria /usr/local/bin/hy2xs-orchestrator
|
||||
|
||||
sudo rm -f /etc/nftables.d/hy2xs.nft
|
||||
sudo sed -i '/nftables.d\/hy2xs.nft/d' /etc/nftables.conf
|
||||
sudo nft -c -f /etc/nftables.conf && sudo nft -f /etc/nftables.conf
|
||||
```
|
||||
|
||||
## После очистки
|
||||
|
||||
Устанавливайте HY2XS v1 обычным путём. PHASE 0 установщика повторит проверку
|
||||
чистоты хоста и подтвердит, что всё в порядке:
|
||||
|
||||
```bash
|
||||
sudo ./install.sh
|
||||
```
|
||||
|
||||
## Незавершённая установка v1 — это другой случай
|
||||
|
||||
Если установка HY2XS v1 упала **после** начала применения изменений, полная
|
||||
очистка не нужна. У такой машины есть корректный маркер состояния текущего
|
||||
поколения, и её чинит `repair`:
|
||||
|
||||
```bash
|
||||
sudo hy2xs-orchestrator repair \
|
||||
--package-dir /usr/local/lib/hy2xs/package \
|
||||
--config /etc/hy2xs/hy2xs.env \
|
||||
--allow-partial-state
|
||||
```
|
||||
|
||||
Флаг `--allow-partial-state` обязателен и осознан: без него `repair` работает
|
||||
только поверх полностью успешной установки. При этом `repair` всё равно
|
||||
проверяет, что маркер принадлежит текущему поколению (`product`,
|
||||
`release_line`, `config_schema_version`), и откажется чинить чужое состояние.
|
||||
|
||||
Отказ вида «install state marker … не относится к текущему поколению HY2XS»
|
||||
означает, что `repair` неприменим и нужна очистка по этому документу.
|
||||
Reference in New Issue
Block a user