🤖 Pull request created from `various-fixes` containing PageHead
breadcrumbs and navigation alignment fixes, Umami analytics proxy, and
infrastructure updates.
8.4 KiB
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 <group>/<action> [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»
Репозитории узлов служат реестрами состояния, а не просто источниками конфигурации: хост сам фиксирует то, что выполняет на практике.
- Регулярная задача
sync/repositoryна хосте коммитит рабочее дерево в веткуsync/<node>(включая указатель субмодуля commons), делает rebase поверхorigin/mainи выполняет push с флагом--force-with-lease. - Запланированное 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, самовосстановление блоков-маркеров), а не остаётся на совести документации.
См. также: