🤖 Pull request created from `various-fixes` containing PageHead
breadcrumbs and navigation alignment fixes, Umami analytics proxy, and
infrastructure updates.
11 KiB
title, description, weight
| title | description | weight |
|---|---|---|
| Действия и оверлей | Контракт действия и затенение действий commons локальными проприетариями узла. | 13 |
Каждая единица автоматизации в apex — это действие: один Python-модуль, который движок диспетчеризует по имени. Оверлей позволяет проприетариям узла добавлять, переопределять или отключать действия «commons» без создания форков. На этой странице описаны контракт действия, декларативные дескрипторы аргументов и правила разрешения.
Контракт действия
Действие — это отдельный файл .py в дереве actions/. Путь к файлу служит именем действия: actions/<group>/<action>.py вызывается как apex <group>/<action> [args...]. Обновлять реестр не нужно: появление файла в дереве сразу публикует действие.
Модуль должен предоставлять две вещи:
METADATA = Meta(...)→ краткое описание и дескрипторы аргументов, управляющие как текстом справки, так и парсингом. Система дескрипторов пришла на смену heredoc-блокуaction_metadata()bash-фреймворка «root» commons, предшественника apex.run(ctx, args)→ точка входа.ctx— сформированный движком контекст выполнения;args— распарсенное пространство имёнargparse.
from engine.descriptor import Meta, Arg, Flag
METADATA = Meta(
summary="Однострочное описание, показываемое в перечислении действий",
args=[
Arg("target", help="Обязательный позиционный аргумент"),
Flag("--dry-run", help="Булев флаг"),
],
)
def run(ctx, args):
...
return 0
Возвращаемое значение run становится кодом завершения процесса. Нецелочисленный результат (включая None) трактуется как успешное завершение (0). Необработанное исключение логируется с префиксом контекста, после чего процесс завершается с кодом 1.
Note
Технически
METADATAнеобязательна: модуль без неё диспетчеризуется с пустымMetaи не принимает аргументов. Однако в реальных действиях её объявлять необходимо, поскольку вывод перечисления и справка--helpгенерируются именно из неё.
Декларативные аргументы
Meta.args — это список дескрипторов. Каждый отображается ровно на одну конструкцию argparse:
| Дескриптор | Отображается на | Поведение |
|---|---|---|
Arg("name") |
позиционный аргумент | Обязателен по умолчанию; required=False делает его опциональным позиционным (nargs="?", по умолчанию None). |
Opt("--name", default=...) |
опция со значением | Опциональный флаг, принимающий значение, с объявленным значением по умолчанию. |
Flag("--name") |
булев флаг | store_true; наличие означает True. |
Rest("name") |
остаток | Жадная сквозная передача всех оставшихся аргументов командной строки (argparse.REMAINDER). |
Движок строит парсер как apex <group>/<action> и разбирает оставшиеся аргументы перед вызовом run. Флаг --help обрабатывается на этапе парсинга. При ошибке использования (неизвестный флаг, отсутствующий позиционный аргумент) выводится справка по синтаксису (usage), а процесс завершается с кодом 64 (EX_USAGE) вместо стандартного для argparse кода 2.
Перечисление без импорта
Команда apex без аргументов (или с флагом --help) выводит список всех доступных действий. Перечисление никогда не импортирует модули действий: движок статически сканирует каждый файл с помощью модуля ast и извлекает только краткое описание METADATA и любую константу DISABLED. Поэтому код действия не выполняется и не может вызвать сбой во время перечисления: файл, который не удалось распарсить, помечается как (unparseable), не нарушая работу всей команды.
Каждая запись помечается своим источником оверлея:
- нет метки → действие commons;
(local)→ существует только в проприетариях;(local override)→ действие проприетариев, затеняющее действие commons;[DISABLED: reason]→ действие объявляет константуDISABLED.
Оверлей
Имена действий разрешаются по двум деревьям, начиная с проприетариев:
{{< filetree/container >}} {{< filetree/folder name="node repository" state="open" >}} {{< filetree/file name="node.env" >}} {{< filetree/folder name="commons" state="open" >}} {{< filetree/folder name="engine" state="closed" >}}{{< /filetree/folder >}} {{< filetree/folder name="actions" state="open" >}} {{< filetree/file name="/.py" >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< filetree/folder name="proprietaries" state="open" >}} {{< filetree/folder name="actions" state="open" >}} {{< filetree/file name="/.py" >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< /filetree/folder >}} {{< /filetree/container >}}
Движок определяет структуру размещения по своему расположению на диске: если запуск происходит из каталога commons/, а в родительском каталоге присутствует node.env, родительский каталог считается корнем репозитория узла, а proprietaries/actions/ — деревом оверлея. Автономный checkout commons сам выступает в качестве корня и не имеет слоя оверлея. Внутри репозитория узла идентичность узла разрешается из FQDN хоста перед диспетчеризацией.
При разрешении имени движок сначала проверяет proprietaries/actions/<name>.py, а затем commons/actions/<name>.py; по найденному пути загружается ровно один модуль. Неизвестное имя считается ошибкой (код завершения 1). Оверлей поддерживает четыре сценария:
- Добавление (Add) → файл, существующий только в проприетариях, становится локальным действием узла и отображается в списке как
(local). - Переопределение (Override) → файл проприетариев по тому же относительному пути полностью затеняет реализацию commons; путь commons помечается при разрешении как
shadowed. - Обёртывание (Wrap) → переопределяющий модуль может делегировать вызов затенённой реализации через
ctx.commons.run(args), дополняя поведение commons локальной логикой узла до или после её вызова. - Отключение (Disable) → модуль с объявлением
DISABLED = "reason"отклоняется при диспетчеризации: движок логирует причину и завершается с кодом1. При перечислении выводится[DISABLED: reason]. Простое значениеDISABLED = Trueтакже отключает действие со стандартной причинойdisabled; пустая строка действие не отключает.
Коды завершения
Действия и движок следуют единому соглашению о кодах завершения:
| Код | Значение | Типичная причина |
|---|---|---|
0 |
успех | Функция run вернула 0 или нецелочисленное значение. |
1 |
общая ошибка | Неизвестное действие, отключённое действие, необработанное исключение, нецелочисленный SystemExit. |
64 |
ошибка использования | Аргументы отклонены парсером (EX_USAGE). |
65 |
ошибка данных | Некорректные входные данные (EX_DATAERR), выбрасывается библиотеками движка. |
66 |
отсутствующий ввод | Требуемый ввод отсутствует (EX_NOINPUT), выбрасывается библиотеками движка. |
См. также: