Расширение Soul Stack
Базовый набор core-модулей покрывает типовые операции — пакеты, файлы, сервисы, пользователи, cron, монтирование и так далее. Когда нужной интеграции в нём нет, Soul Stack расширяется плагинами — отдельными исполняемыми файлами, которые подключаются к системе по единому протоколу, без модификации ядра.
Это тот же путь к паритету с экосистемами зрелых инструментов: core-набор — нативный Go-код, а нишевые и специфичные для организации интеграции пишутся как плагины через публичный Go SDK. SDK и плагины — под Apache 2.0; свой модуль вы вправе публиковать под любой лицензией, включая проприетарную. Ядро при этом под BSL 1.1 (fair-code), но плагинов это не касается: они отдельные процессы через gRPC, а не производная работа ядра.
Core-модули vs плагины
Заголовок раздела «Core-модули vs плагины»| Core-модуль | Плагин | |
|---|---|---|
| Где живёт | статически встроен в исполняемый файл soul / keeper | отдельный исполняемый файл |
| Установка | не нужна, версия = версия сборки | поставляется как самостоятельный артефакт |
| Кто пишет | поставляется с Soul Stack | вы, ваша организация или сообщество |
| Язык | Go (в ядре) | любой язык с gRPC; Go SDK — готовый |
| Изоляция | в адресном пространстве host-процесса | отдельный процесс, gRPC через сокет |
Каталог встроенных модулей — Модули. Этот раздел — про то, как добавить своё.
Модель плагинов
Заголовок раздела «Модель плагинов»Плагин — это отдельный исполняемый файл, который host-процесс (soul или keeper) запускает как дочерний процесс (sub-process) на время операции. Общение идёт не через stdin/stdout-парсинг, а по gRPC через Unix domain socket:
- Host запускает исполняемый файл-плагин как дочерний процесс и передаёт ему путь к сокету через переменную окружения.
- Плагин при старте пишет в stdout одну строку handshake — JSON с магическим полем-маркером, версией протокола и адресом сокета. Все строки до неё host игнорирует (защита от случайного вывода в
init()или из библиотек). - Дальше host и плагин общаются по gRPC поверх этого сокета.
- По завершении операции host штатно гасит плагин сигналом (graceful shutdown с grace-периодом).
Lifecycle — one-shot: плагин поднимается на операцию и завершается после неё. Это та же модель «one-line handshake → gRPC-over-socket», что у Terraform-провайдеров и Vault-плагинов (идея, а не код: библиотека hashicorp/go-plugin в зависимости не тянется, формат свой).
Сокет — файл с правами 0700, владелец — служебный пользователь host-процесса; лежит в host-managed директории. Защита канала — на уровне прав файловой системы: чужой процесс физически не откроет сокет. TLS на plugin-сокете не используется — для Unix-сокета с правами 0700 он не даёт выигрыша.
Три типа плагинов
Заголовок раздела «Три типа плагинов»Инфраструктура для всех трёх типов единая — один и тот же handshake, способ запуска, формат манифеста и версионирование. Различается только gRPC-контракт (набор методов), который плагин реализует, и кто его запускает.
| Тип (kind) | Исполняемый файл | Host | Что делает |
|---|---|---|---|
| SoulModule | soul-mod-<имя> | soul-агент (на хосте) | Реализует шаг Destiny: приводит ресурс к состоянию (Validate / Apply, идемпотентно). |
| CloudDriver | soul-cloud-<провайдер> | keeper (на сервере) | Создаёт / удаляет / опрашивает VM у облачного провайдера. |
| SshProvider | soul-ssh-<провайдер> | keeper (на сервере) | Поставляет SSH-credentials для push-режима. |
Имя исполняемого файла (soul-mod-* / soul-cloud-* / soul-ssh-*) — соглашение, а тип плагина определяется полем kind в его манифесте.
- Как написать SoulModule — пошагово: интерфейс SDK, идемпотентность, сборка исполняемого файла, как его подхватывает агент.
- CloudDriver и SshProvider — обзор серверных плагинов.
Публичный SDK
Заголовок раздела «Публичный SDK»Плагины пишутся на Go через публичный SDK. Он закрывает всю механику протокола, чтобы автор плагина писал только бизнес-логику:
- handshake-helper — читает путь к сокету, пишет handshake-строку, поднимает gRPC-сервер, обрабатывает сигнал завершения;
- типизированные интерфейсы для каждого из трёх контрактов (SoulModule / CloudDriver / SshProvider);
- типы манифеста плагина.
Зависимость минимальна: автор плагина подключает только модули SDK и контрактов плагинов — без кода Keeper-а или Soul-агента. Подробнее про сборку и интерфейс — в Как написать SoulModule.
Каркас нового SoulModule-плагина генерируется командой soul-lint plugin-init — это даёт готовое дерево проекта, остаётся написать Apply.
Манифест плагина
Заголовок раздела «Манифест плагина»Рядом с исполняемым файлом — статический manifest.yaml. Он описывает плагин без его запуска: тип (kind), версию протокола, имя, поддерживаемые состояния и их параметры, требуемые от host-а возможности (required_capabilities) и затрагиваемые ресурсы (side_effects).
Манифест читает soul-lint при статической проверке Destiny — ловит неизвестный модуль, неизвестное состояние, неверные параметры и нехватку прав до применения на хостах, не поднимая плагин-процесс. Формат манифеста подробнее — в Как написать SoulModule.
Что дальше
Заголовок раздела «Что дальше»- Как написать SoulModule — основной сценарий расширения.
- CloudDriver и SshProvider — серверные плагины.
- Каталог core-модулей — что уже есть из коробки.
- soul-lint — статическая валидация и scaffold плагина.