# Очистка сервера от предыдущей установки ## Зачем этот документ 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» у скрипта нет намеренно. `/usr/local/bin/hysteria` входит в clean-host контракт установщика: сервер, где он остался, установку HY2XS v1 не пройдёт. Скрипт, который сохранял бы бинарник и при этом сообщал «хост чист», прямо противоречил бы следующему запуску `install.sh`. Свежая установка всё равно кладёт собственную версию Hysteria, проверенную по SHA-256 против upstream `hashes.txt`. В конце скрипт сам проверяет, что хост стал чистым по тому же контракту, который применяет установщик. Если что-то осталось, он назовёт конкретные объекты и завершится с ошибкой. ## Что скрипт делает и чего не делает Делает: 1. останавливает и выключает `hysteria-server`, `hy2xs-admin`, `h-ui`; 2. снимает таймеры отката firewall `hy2xs-fw-rollback-*` — они переживают неудачную установку и иначе продолжили бы менять ruleset уже после очистки; 3. удаляет unit-файлы и выполняет `daemon-reload`; 4. удаляет каталоги приложения, конфигурации, данных и логов, включая `/var/lib/hysteria` (там остаётся ACME-состояние и сертификаты Hysteria), `/usr/local/lib/hy2xs` и symlink `/usr/local/bin/hy2xs-orchestrator`; 5. удаляет `/usr/local/bin/hysteria`; 6. удаляет артефакты незавершённой операции в `/run`: каталог отката `/run/hy2xs` (прежние `nftables.conf`, `hy2xs.nft` и маркер срабатывания guard) и замок операций `/run/lock/hy2xs-orchestrator.lock`, который может пережить убитый `kill -9` процесс оркестратора и не дать запуститься следующей установке. `/run` — tmpfs, и перезагрузка убрала бы оба, но очистка не имеет права требовать перезагрузки; 7. удаляет `*.candidate` firewall — они остаются, если операция упала между `nft -c` и подстановкой файла в production-путь; 8. удаляет фрагмент `/etc/nftables.d/hy2xs.nft` и строку `include` для него из `/etc/nftables.conf`, после чего перезагружает ruleset; 9. проверяет чистоту хоста. Список удаляемых путей и список legacy-маркеров clean-host контракта описывают одну и ту же границу: расхождение между ними ловится приёмкой сборки. Иначе возможен сервер, с которого «всё удалено», но который установщик всё равно считает грязным — или, что хуже, наоборот. Не делает: - не трогает `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 от незавершённой установки. # --plain обязателен: у юнита в состоянии failed первой колонкой идёт маркер `●`, # и без флага такой юнит легко пропустить — а это ровно те, что остались после # аварийной установки. sudo systemctl list-units --all --plain 'hy2xs-fw-rollback-*' # для каждого найденного юнита: # sudo systemctl stop && sudo systemctl disable # sudo systemctl reset-failed # sudo rm -f /etc/systemd/system/ 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 # артефакты незавершённой операции в /run (tmpfs) sudo rm -rf /run/hy2xs sudo rm -f /run/lock/hy2xs-orchestrator.lock # candidate-файлы firewall от операции, упавшей до подстановки sudo rm -f /etc/nftables.conf.candidate /etc/nftables.d/hy2xs.nft.candidate 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` неприменим и нужна очистка по этому документу.