Files
ermnvldmr.com/services/docs/content/ru/apex/concepts/actions-and-overlay.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

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), выбрасывается библиотеками движка.

См. также: