Метки раннеров и таргетинг
Раннер может нести произвольные метки — короткие теги вроде
linux, gpu, prod, staging, region-eu. При запуске нагрузочного
теста, фаззинга, хаос-эксперимента или test plan Mockarty маршрутизирует
задачу только на те раннеры, чьи метки удовлетворяют требованию.
Способов указать требование два:
| Режим | Когда выбирать | Что пишете |
|---|---|---|
| Простой (чипы) | Каждому раннеру нужны все перечисленные метки. Самый частый случай. | linux, gpu, prod (по одному чипу, неявный AND) |
| Расширенный (DSL) | Нужен OR, NOT, регекс или скобки. | `linux & (gpu |
В UI у пикера есть переключатель Простой / Расширенный справа от
поля с чипами. При переходе из Простого в Расширенный выражение
предзаполняется конкатенацией чипов через &. Обратное переключение
доступно, только когда выражение — чистое AND из литеральных атомов.
Задаём метки раннеру
Откройте Админ → Интеграции, нажмите Изменить метки
рядом с раннером и добавьте чипы. Метка — 1–64 символа из набора
a-z, 0-9, ., -, _. Заглавные буквы автоматически приводятся
к нижнему регистру.
Для эфемерных раннеров метки можно передать через переменную окружения
RUNNER_LABELS=linux,gpu,ci при запуске процесса.
Простой режим (чипы)
Добавьте один или несколько чипов. Раннер подходит только тогда, когда
его набор меток является надмножеством вашего списка чипов:
| Чипы | Подходят |
|---|---|
linux |
любой раннер с меткой linux |
linux, gpu |
только раннеры, у которых есть обе метки |
Порядок не важен. Каждый добавленный чип сужает выбор, но никогда не
расширяет.
Расширенный режим (label DSL)
Переключитесь на Расширенный и впишите выражение. Грамматика:
expr := orExpr
orExpr := andExpr ('|' andExpr)*
andExpr := notExpr ('&' notExpr)*
notExpr := '!' notExpr | atom
atom := литерал | регекс | '(' expr ')'
литерал := [a-z0-9._-]{1,64}
регекс := '/' pattern '/' flags?
flags := 'i'
&— AND (обе стороны должны совпасть)|— OR (достаточно одной стороны)!— NOT (сторона не должна совпасть)(...)— группировка, переопределяет приоритет/.../— регулярное выражение по набору меток; совпадение, если
хотя бы одна метка матчит паттерн. Разрешён только флагi
(case-insensitive).
Приоритет (от высшего к низшему): !, &, |. То есть
linux & gpu | tpu парсится как (linux & gpu) | tpu. Когда не
уверены — используйте скобки.
Примеры
linux & gpu эквивалент Простого [linux, gpu]
linux & (gpu | tpu) Linux + любой ускоритель
linux & !staging Linux, но не staging-флот
/^perf-.*/i & ci любой раннер "perf-…", который ещё и "ci"
(prod | staging) & region-eu только ЕС, prod или staging
!arm64 любой не-ARM раннер
Лимиты
Парсер защищается жёсткими ограничениями — некорректное выражение не
может заставить диспетчер делать неограниченную работу:
| Лимит | Значение |
|---|---|
| Максимальная длина выражения | 1024 байта |
| Максимальная глубина вложенности | 16 |
| Максимум литералов + регексов | 64 |
| Максимум регексов | 8 |
| Максимальная длина паттерна регекса | 256 байт |
| Разрешённые флаги регекса | только i |
При превышении лимита badge под полем покажет точный байтовый офсет и
правило, которое нарушено.
Live-валидация
По мере набора Mockarty шлёт запрос на POST /api/v1/runner-labels/validate
и показывает один из вариантов:
подходит раннеров онлайн: N— зелёный, выражение корректно и
N онлайн-раннеров под него подходят. Под пикером отображается
превью первых 5 имён.подходит раннеров онлайн: 0— янтарный, парсится, но сейчас
никто не совпадает. Задача встанет в очередь и подождёт подходящего
раннера.Некорректное выражение, байт N: <причина>— красный. Исправьте
синтаксис; диспетчер откажется принимать выражение с ошибкой.
Валидация дебаунсится на 300 мс, чтобы быстрый ввод не спамил сервер.
Где применяются метки
Таргетинг работает одинаково везде, где задача уходит на раннер:
| Поверхность | Поле в payload |
|---|---|
POST /api/v1/perf/run |
requiredRunnerLabels[] или runnerLabelExpr |
POST /api/v1/fuzzing/run |
requiredRunnerLabels[] или runnerLabelExpr |
| Test Plan item | runnerLabels[] (на каждый item) |
| Функциональный запуск API tester | requiredRunnerLabels[] или runnerLabelExpr |
| Запуск Test Case / UI-теста | наследуется от TCM-конфигурации запуска (см. ниже) |
requiredRunnerLabels и runnerLabelExpr в UI взаимоисключающие —
пикер посылает одно из двух в зависимости от режима. Если оба попадут
в диспетчер, они комбинируются через AND (выражение всегда сужает
набор чипов, не расширяет).
Маршрутизация запусков Test Case (и UI-тестов) через конфигурацию
У запуска Test Case нет собственного пикера меток — вместо этого он
наследует runner-селектор от TCM-конфигурации, против которой
запущен. Так селектор остаётся переиспользуемым: «конфигурация EU smoke
всегда гоняется на флоте region-eu» объявляется один раз на
конфигурации, и каждый запуск с ней маршрутизируется одинаково. Каждый
шаг с внешним раннером, который порождает запуск — UI-тест (browser
runner), нагрузочный, API-тест, фаззинг — наследует тот же селектор.
Конфигурация объявляет селектор двумя опциональными полями:
| Поле | Тип | Значение |
|---|---|---|
runnerLabels |
массив строк | Чипы простого режима — раннер должен нести все (надмножество, неявный AND). |
runnerLabelExpr |
строка | DSL расширенного режима (та же грамматика, что выше). Комбинируется с runnerLabels через AND. |
Поля задаются на конфигурации через API конфигураций, например:
# Создать конфигурацию, привязанную к EU GPU-флоту
curl -X POST "$MOCKARTY/api/v1/namespaces/$NS/tcm/configurations" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{
"name": "EU smoke",
"isDefault": true,
"params": { "runnerLabels": ["region-eu", "gpu"] }
}'
При старте запуска кейса выберите конфигурацию опциональным полем
configurationId:
curl -X POST "$MOCKARTY/api/v1/namespaces/$NS/test-cases/$CASE_ID/run" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{ "mode": "semi_automatic", "configurationId": "'$CONFIG_ID'" }'
- Явный
configurationId— запуск использует селектор этой
конфигурации. Неизвестный id (или из другого namespace) отклоняется с
400/404, чтобы опечатка не привела к запуску без селектора. - Без
configurationId— запуск откатывается к конфигурации
кейса по умолчанию (помеченной default). Если у кейса нет
default-конфигурации, запуск идёт без селектора (матчинг только по
namespace + capability, как и раньше).
Если конфигурация не объявляет селектор, запуск идёт без селектора.
Запуск, чей селектор не матчит ни одного онлайн-раннера, встаёт в
очередь и ждёт появления подходящего раннера (UI-тесты дополнительно
требуют раннер с capability ui-test — см. «Запись UI-тестов»).
Простой или Расширенный — что выбрать?
Простой подходит, когда:
- правило формулируется как «у каждого раннера должны быть эти теги»;
- набор тегов короткий (1–4);
- OR / NOT / регекс не нужны.
Расширенный оправдан, когда:
- у раннеров есть пулы, которые удобно адресовать по шаблону имени
(/^perf-.*/i); - нужно OR («любой раннер с
gpuИЛИtpu»); - нужно NOT («всё, кроме
staging»); - правила вложенные.
Простой режим быстрее писать и читать с разбегу; Расширенный строго
выразительнее, но требует внимания при чтении. Для CI-раннбука
выражение естественно живёт в версионируемом конфиге; для разовых
запусков обычно хватает Простого.
Хорошие практики
- Думайте о метках как о Kubernetes node labels — описывайте,
что раннер из себя представляет, а не что нужно задаче
(gpu✓,ml-training-job✗). - Держите словарь меток компактным. Чип-пикер автодополняет из
существующего словаря; «джунгли тегов» становится тяжело навигировать. - Договоритесь о стабильной схеме:
region-eu,region-us,
os-linux,arch-amd64. Точка/дефис хорошо читаются в выражениях. - Регекс — крайний случай, когда литеральным набором действительно
нельзя описать когорту. Это самый медленный путь оценки. - Для конкретного железа (например, модель GPU) лучше отдельный
литерал (gpu-a100), а не регекс (/^gpu-a100.*/).