Files
HY2XS_flamy/docs
founder e84fdedc4b fix(v1): сделать откат неотменяемым, а маркер установки — долговечным
Три дефекта одного класса в failure path install/reconfigure.

1. Запись состояния отказа отменяла откат.

   Обработчик ошибки первым делом писал в install-state фазу отказа обычным
   await и только потом откатывался. Эта запись — mkdir, write и chown в
   /var/lib/hy2xs, то есть она падает ровно там, где откат нужнее всего:
   заполненный диск, read-only ФС, ошибка ввода-вывода. Бросок уносил
   управление наружу, и обязательное восстановление не выполнялось вовсе —
   применённый firewall и развёрнутые сервисы оставались на сервере.

   Необязательная телеметрия состояния стояла перед обязательным
   восстановлением. Для диагностики это уже было закрыто, для записи
   состояния — нет.

2. Откат отменял сам себя.

   Он был написан цепочкой await, а каждая его стадия — systemctl, cp, rm -rf
   и nft, то есть умеет упасть сама. Отказ первой стадии отменял все
   последующие. В reconfigure это означало сервер одновременно с применённым
   сломанным firewall И без восстановленных из /etc/hy2xs/backups конфигов.
   Внутри rollbackCurrentState болезнь та же: единственная команда без
   `|| true` (systemctl daemon-reload) отменяла перезапуск сервисов строкой
   ниже, и восстановленные unit-файлы не применялись.

   Стадии стали независимыми: выполняются все, отказавшие перечисляются в
   журнале, наружу уходит исходная ошибка операции.

3. У маркера установки было два писателя с разными гарантиями.

   install перезаписывал файл на месте (writeText), reconfigure подставлял
   атомарно. Слабейшая гарантия досталась команде, которая этот файл создаёт.
   Перезапись на месте укорачивает файл до нуля и только потом наполняет:
   отказ между этими моментами оставляет половину JSON, который не
   разбирается — reconfigure видит его как отсутствующий, clean-host как
   присутствующий, а хост уже изменён.

   Атомарности при этом мало. rename() без fsync даёт атомарность видимости
   без долговечности: после потери питания ext4 штатно отдаёт по этому пути
   нулевой файл. Для метаданных восстановления это неприемлемо, поэтому
   порядок теперь: права/владелец -> fsync файла -> rename -> fsync каталога.

   Заодно ownership-флаг переименован в stateTouched и взводится ДО записи:
   отказ на chown после успешного write оставлял файл на диске при
   невзведённом флаге, то есть давал fatal_pre_apply («ничего не изменено»)
   при уже существующем маркере установки.

Тесты: rollback-mandatory.test.ts (внедрение отказа в стадию, проводка команд),
atomic-write.test.ts (замена целиком, прежний файл при отказе, отсутствие
временных файлов, права, guard). Приёмка сборки закрепляет порядок шагов
атомарной записи, отсутствие незащищённой записи состояния в обработчиках и
отсутствие отменяемых цепочек в откате.
2026-08-30 18:11:55 +05:00
..

HY2XS baseline docs

Этот набор документов фиксирует актуальную baseline-модель HY2XS под следующие ограничения:

  • серверный транспорт: ванильная Hysteria2
  • UI: HY2XS admin, штатный компонент проекта, поставляется вместе с пакетом
  • target OS: только чистый Debian 13
  • оркестратор: install-only, только первичная установка и базовая настройка
  • стек оркестратора: Bun + TypeScript
  • target-side build: запрещён
  • standalone update / rollback / uninstall subcommands: вне scope
  • сборка и упаковка: отдельный локальный build layer
  • post-install state: /etc/hysteria/post-install.env
  • установка: только на чистый хост, миграция с 0.x не поддерживается
  • контракт версий продукта/платформы/toolchain: корневой versions.env
  • клиентский delivery/access layer: вне baseline этого пакета docs

Главная архитектурная схема

В этой редакции зафиксированы два слоя:

  1. Builder layer — работает на отдельном Debian 13 amd64 build host. Он собирает итоговый пакет, собирает HY2XS admin, компилирует Bun/TypeScript оркестратор в install-артефакт, упаковывает шаблоны, unit-файлы и примеры конфигов.

  2. Runtime / target layer — работает на чистом Debian 13. Здесь нет сборщика. Здесь запускается только итоговый install package / orchestrator, который:

    • ставит системные зависимости
    • разворачивает встроенный HY2XS admin
    • забирает закреплённую в пакете Hysteria2 из официального upstream и сверяет её по SHA-256 и версии
    • создаёт конфиги, systemd unit-файлы и post-install.env
    • выполняет базовую настройку сервера

Версия Hysteria2 выбирается на builder layer: последняя стабильная разрешается при сборке и замораживается в metadata пакета. Target layer никогда не обращается к moving latest.

Базовые правила

  1. Hysteria2 не вендорится и не собирается как часть HY2XS.
  2. HY2XS admin — штатный компонент проекта и поставляется вместе с пакетом.
  3. Оркестратор пишется на Bun + TypeScript.
  4. На target нет npm / pnpm / yarn / bun install / transpile step.
  5. На target нет standalone логики update / rollback / uninstall.
  6. В install/reconfigure есть bounded rollback для failure-сценариев firewall/systemd/config/smoke. Rollback опирается на то, что операция реально успела применить: сервисы, которые она не разворачивала, не останавливаются никогда.
  7. Установка двухфазная: PHASE 0 — read only, PHASE 1 — mutation. До успешного clean-host preflight на сервере не изменяется ни один persistent path. У мутирующей фазы ровно один владелец — оркестратор: install.sh проверяет и передаёт управление, не изменяя ничего сам. Очистка предыдущей установки — отдельная явная операция оператора, см. 14-legacy-cleanup.md.
  8. Выдача доступа пользователям, Telegram-бот, billing, backend профилей и похожие контуры не входят в этот baseline.

Состав документов

  1. 01-architecture-baseline.md
  2. 02-build-layer-and-package.md
  3. 03-server-hysteria2.md
  4. 04-admin-panel.md
  5. 05-client-and-access-scope.md
  6. 06-speed-limits-and-congestion.md
  7. 07-systemd-and-firewall.md
  8. 08-orchestrator-spec.md
  9. 09-post-install-env.md
  10. 10-access-layer-out-of-scope.md
  11. 11-testing-and-acceptance.md
  12. 12-operations-and-troubleshooting.md
  13. 13-production-runbook.md
  14. 14-legacy-cleanup.md

История изменений проекта — в CHANGELOG.md.

Жёсткие рамки baseline

Не делаем:

  • upgrade manager
  • rollback manager
  • uninstall
  • reconcile engine
  • target-side build pipeline
  • Docker baseline
  • multi-node
  • port hopping
  • Telegram-бот
  • backend выдачи remote profiles
  • «умную» миграцию сломанных старых инсталляций

Одной фразой

Правильная baseline-модель теперь такая:

Локальный builder разрешает последнюю стабильную Hysteria2, проверяет её на совместимость с конфигом HY2XS и собирает install package с HY2XS admin и Bun/TypeScript оркестратором; серверный install-only orchestrator ставит этот пакет на чистый Debian 13, скачивает ровно закреплённую Hysteria2, разворачивает HY2XS admin, создаёт systemd + nftables + post-install env и подготавливает рабочее серверное окружение.