|
| 1 | +--- |
| 2 | +title: Руководство для разработчиков ядра |
| 3 | +--- |
| 4 | + |
| 5 | +Это руководство описывает внутреннюю архитектуру Exordos Core: как элементы, манифесты и ресурсы |
| 6 | +хранятся и приводятся в соответствие (reconcile) на вычислительных нодах. Оно предназначено для тех, кто |
| 7 | +работает над самим Exordos Core. Если вы хотите разработать элемент поверх платформы, см. |
| 8 | +[Руководство для разработчиков приложений](../app-developer-guide/index.ru.md). |
| 9 | + |
| 10 | +## Элементы, манифесты и ресурсы |
| 11 | + |
| 12 | +Установка элемента (`exordos em elements install <manifest.yaml>`) создаёт набор связанных записей, |
| 13 | +описанных в `exordos_core/elements/dm/models.py`: |
| 14 | + |
| 15 | +| Модель | Таблица | Назначение | |
| 16 | +|---|---|---| |
| 17 | +| `Manifest` | `em_manifests` | Разобранный YAML-манифест (resources, imports, exports, requirements) | |
| 18 | +| `Element` | `em_elements` | Установленный элемент (имя, версия, статус) | |
| 19 | +| `Resource` | `em_resources` | Отдельный задекларированный ресурс внутри элемента | |
| 20 | +| `Import` | `em_imports` | Какой ресурс какого элемента импортирован | |
| 21 | +| `Export` | `em_exports` | Ресурс, опубликованный для импорта другими элементами | |
| 22 | + |
| 23 | +## Element engine |
| 24 | + |
| 25 | +`ElementEngine` — реестр в памяти со всеми установленными элементами и их ресурсами, загружаемый из базы |
| 26 | +данных через `load_from_database()`. Каждый элемент представлен как `Namespace`, а ресурсы внутри него |
| 27 | +адресуются по строке-ссылке (например, `$my_element.compute.nodes.$my_node`). Реестр перезагружается при |
| 28 | +установке, обновлении или удалении манифеста, а также лениво — на первой итерации цикла reconciliation. |
| 29 | + |
| 30 | +## Reconciliation: от задекларированного ресурса до работающей ноды |
| 31 | + |
| 32 | +Reconciliation выполняет `ElementManagerBuilder` (`elements/services/builders.py`) — сервисный цикл, |
| 33 | +тикающий примерно раз в 3 секунды: |
| 34 | + |
| 35 | +1. Перебрать все ресурсы, известные element engine. |
| 36 | +2. Отрендерить `value` ресурса в `target_state`, разрешив ссылки `$link` и интерполяции `f"..."` (см. |
| 37 | + [Рендеринг значений манифеста](#рендеринг-значений-манифеста)). |
| 38 | +3. Создать или обновить запись `TargetResource` (таблица `ua_target_resources` из `gcl_sdk`) — это |
| 39 | + контракт с агентом на стороне ноды. |
| 40 | +4. Universal Agent, работающий на целевой вычислительной ноде, следит за `ua_target_resources` на предмет |
| 41 | + записей своего `kind`, применяет их к реальной системе (systemd-юнит, VM, диск, конфигурационный файл |
| 42 | + и т.д.) и записывает обратно `actual_resource`. |
| 43 | +5. `ElementManagerBuilder` сравнивает хэш `actual_resource` с `target_state` и обновляет |
| 44 | + `Resource.status` соответственно. |
| 45 | +6. Итоговый статус элемента выводится из статусов всех его ресурсов. |
| 46 | + |
| 47 | +## Жизненный цикл статусов |
| 48 | + |
| 49 | +`Element` и `Resource` используют общий enum `Status` с тремя значениями: `NEW → IN_PROGRESS → ACTIVE`. |
| 50 | +На этом уровне нет статуса `ERROR` — ресурс, который не может сойтись, просто остаётся в `IN_PROGRESS`. |
| 51 | + |
| 52 | +У некоторых типов ресурсов есть собственный, более богатый жизненный цикл. `Service` (таблица |
| 53 | +`em_services`) и `Config` (таблица `config_configs`) добавляют статус `ERROR` к `NEW`/`IN_PROGRESS`/ |
| 54 | +`ACTIVE`, поскольку эти подсистемы способны обнаружить и сообщить о неудачном применении. |
| 55 | + |
| 56 | +## Рендеринг значений манифеста |
| 57 | + |
| 58 | +`_render_value` (`elements/dm/models.py`) превращает строку из манифеста в конкретное значение: |
| 59 | + |
| 60 | +- Строка, начинающаяся с `$`, разрешается как ссылка на ресурс. |
| 61 | +- Строка, начинающаяся с `f"`, трактуется как inline-шаблон: плейсхолдеры `{$element.type.$name:field}` |
| 62 | + внутри неё подставляются. |
| 63 | +- Любая другая строка возвращается без изменений. |
| 64 | + |
| 65 | +Автор манифеста, забывший префикс `f"`, не получает молча пустое значение — буквальный текст `{$...}` |
| 66 | +остаётся в результирующем выводе, где бы это значение ни оказалось (в конфигурационном файле, в командной |
| 67 | +строке сервиса и т.д.). См. [Диагностику проблем](../usage/troubleshooting.ru.md) — там описаны симптомы, |
| 68 | +к которым это приводит. |
| 69 | + |
| 70 | +## Основные типы ресурсов ядра |
| 71 | + |
| 72 | +- `$core.compute.nodes` / `$core.compute.sets` — виртуальные машины и группы нод (KVM/QEMU) |
| 73 | +- `$core.em.services` — systemd-сервисы на ноде или группе нод |
| 74 | +- `$core.vs.variables` — Variable Store, используется для платформенных значений по умолчанию |
| 75 | +- `$core.config.configs` — файлы, доставляемые на ноду; требует `project_id` и `body.kind`, см. |
| 76 | + [Диагностику проблем](../usage/troubleshooting.ru.md) |
| 77 | + |
| 78 | +## См. также |
| 79 | + |
| 80 | +- [Справочник по манифесту](../em/manifest.ru.md) |
| 81 | +- [Service as a Service API](../em/service.md) |
| 82 | +- [Диагностика проблем](../usage/troubleshooting.ru.md) |
0 commit comments