Files
ermnvldmr.com/services/docs/content/ru/apex/concepts/architecture.md
T
deytenit 9ee672504f fix: PageHead header alignment, analytics proxy, and infra improvements (#64)
🤖 Pull request created from `various-fixes` containing PageHead
breadcrumbs and navigation alignment fixes, Umami analytics proxy, and
infrastructure updates.
2026-10-24 16:52:49 +03:00

8.4 KiB
Raw Blame History

title, description, weight
title description weight
Архитектура фреймворка Четыре опоры репозиториев узла, субмодуль commons и поток диспетчеризации. 11

Фреймворк apex делит автоматизацию флота между одним общим репозиторием («commons») и отдельными репозиториями для каждого узла. В commons сосредоточено всё общее для флота: движок, стандартные действия и ядровая композиция. Репозиторий узла содержит специфичные для хоста данные: его идентичность, хостовые конфигурации, сервисные композиции и локальные проприетарии.

Четыре опоры

Каждый репозиторий узла имеет одинаковую структуру:

{{< filetree/container >}} {{< filetree/folder name="." state="open" >}} {{< filetree/folder name="commons" state="closed" >}}{{< /filetree/folder >}} {{< filetree/folder name="proprietaries" state="closed" >}}{{< /filetree/folder >}} {{< filetree/folder name="configs" state="closed" >}}{{< /filetree/folder >}} {{< filetree/folder name="compositions" state="closed" >}}{{< /filetree/folder >}} {{< filetree/file name="node.env" >}} {{< filetree/file name="init.sh" >}} {{< /filetree/folder >}} {{< /filetree/container >}}

Опора Содержимое Владение
commons/ Git-субмодуль → apex.ermnvldmr.com, закреплённый на релизном теге Общее, версионируемое
proprietaries/ Узло-локальные действия, библиотеки и исходники инструментов (накладываются оверлеем поверх commons) Узел
configs/ Исходники конфигурации хоста: ufw/, cron/crontab, systemd/, crowdsec/ Узел
compositions/ По одному каталогу на проект, ядровая обёртка apex/ и реестр адресации Узел

Фиксация субмодуля — версионный контракт фреймворка: узел выполняет именно ту версию движка и ядровой композиции, которая зафиксирована в его gitlink. Обновление узла выполняется явно: достаточно переключиться на новый тег внутри commons/ и закоммитить изменённый указатель.

Поток диспетчеризации

Лаунчер commons/apex работает с локальным чекаутом; передавать узел в качестве аргумента не нужно нигде.

flowchart TD
    A["apex &lt;group&gt;/&lt;action&gt; [args]"] --> B{Схема размещения}
    B -- "каталог commons/ с node.env рядом" --> C[Checkout узла:<br/>оверлей = proprietaries/actions]
    B -- иначе --> D[Автономный commons:<br/>без оверлея]
    C --> E["Разрешение оверлея<br/>(сначала proprietaries)"]
    D --> E
    E --> F["Разрешение идентичности<br/>(FQDN + node.env)"]
    F --> G["Построение ctx<br/>(log, sys, tpl, host, ufw,<br/>crowdsec, systemd, notify)"]
    G --> H["разбор аргументов (Meta)"]
    H --> I["run(ctx, args)"]

Движок определяет режим работы по своему расположению на диске. Если он запущен из каталога commons/, а в родительском каталоге присутствует node.env, то родительский каталог принимается за корень репозитория узла, а proprietaries/actions/ становится деревом оверлея. При любом другом расположении commons считается автономным чекаутом и выступает собственным корнем.

Команда перечисления (apex --help) никогда не импортирует модули действий: краткие описания и маркеры отключения извлекаются статически с помощью модуля ast. При диспетчеризации загружается ровно один модуль по вычисленному пути. Подробнее — в разделе Концепция: Действия и оверлей.

Модель «capture-up»

Репозитории узлов служат реестрами состояния, а не просто источниками конфигурации: хост сам фиксирует то, что выполняет на практике.

  1. Регулярная задача sync/repository на хосте коммитит рабочее дерево в ветку sync/<node> (включая указатель субмодуля commons), делает rebase поверх origin/main и выполняет push с флагом --force-with-lease.
  2. Запланированное CI-задание в репозитории узла вливает ветку sync/<node> обратно в main от имени бота.

Благодаря циклу «capture-up» любой дрейф конфигурации на хосте превращается в коммит: изменение наглядно отображается в diff и легко откатывается, исключая незаметные расхождения. Если субмодуль commons имеет незакоммиченные изменения («грязный») или каталог compositions/ отсутствует, синхронизация прерывается без коммита, поэтому повреждённое состояние чекаута никогда не попадёт в историю.

Note

CI-задание слияния клонирует репозиторий без субмодулей: субмодуль commons подключён по SSH-URL, недоступному стандартному токену CI, а самому слиянию требуется лишь обновить указатель gitlink.

Проектные ограничения

  • Только стандартная библиотека (stdlib). Движок работает на штатном Python 3 из Debian — без pip и сторонних зависимостей. Каталог vendor/ зарезервирован для зафиксированного чистого Python-кода, но по умолчанию поставляется пустым.
  • Ручные compose-файлы. Никаких промежуточных манифестов или кодогенерации: файлы compose служат единственным источником истины.
  • Автоматическая проверка вместо соглашений. Всё, что можно проверить или применить автоматически, выполняется действием (проверка якорных IP, откат crontab, самовосстановление блоков-маркеров), а не остаётся на совести документации.

См. также: