63 lines
4.7 KiB
Markdown
63 lines
4.7 KiB
Markdown
---
|
||
work_item: ORCH-111
|
||
stage: architecture
|
||
author_agent: architect
|
||
status: proposed
|
||
created_at: 2026-06-15
|
||
model_used: claude-opus-4-8
|
||
---
|
||
|
||
# 07 — Инфра-требования: ORCH-111 — watchdog-алерт на долго живущий тест-процесс
|
||
|
||
Work Item: **ORCH-111** · Repo: **orchestrator** · Стадия: architecture
|
||
|
||
> Применимо: меняется топология контейнера-наблюдателя (`pid: host`) и добавляются env-ключи
|
||
> watchdog. Решение — `06-adr/ADR-001` + сквозной `adr-0041`.
|
||
|
||
## I-1. Топология / окружения
|
||
- **Изменение:** сервису `orchestrator-watchdog` в `docker-compose.yml` добавляется **`pid: host`**
|
||
(ADR-001 D6). Под `pid: host` контейнерный `/proc` отражает корневой PID-namespace хоста →
|
||
watchdog видит таблицу процессов хоста (включая осиротевшие pytest, репарентированные на tini
|
||
orchestrator-контейнера). **Отдельный mount `/proc` не требуется** (procfs зависит от namespace
|
||
читателя).
|
||
- `pid: host` — **НЕ volume** → существующий тест `tests/watchdog/test_compose_service.py::
|
||
test_host_paths_mounted_read_only` (требует `:ro` на каждом volume) остаётся зелёным; разработчик
|
||
добавляет позитивный тест на наличие `pid: host`.
|
||
- Привилегия — **только у наблюдателя** (`orchestrator-watchdog`). Прод `orchestrator` и
|
||
`orchestrator-staging` **не** меняются. Прочие тома/порты/сеть watchdog — без изменений
|
||
(`network_mode: host`, `docker.sock:ro`, `/repos:ro`, `./data:ro`, `mem_limit: 128m`).
|
||
- **Тираж (Lite/Bundled, ORCH-102/103):** `pid: host` входит в канонический compose sidecar; сигнал
|
||
дефолт-off → нулевое изменение поведения у тиражных инсталляций.
|
||
|
||
## I-2. Переменные окружения / секреты
|
||
- **Новые ключи** (ADR-001 D5), парсеры never-raise:
|
||
| Ключ | Дефолт | Смысл |
|
||
|------|--------|-------|
|
||
| `WATCHDOG_PROC_ENABLED` | `false` | kill-switch / осознанный opt-in |
|
||
| `WATCHDOG_PROC_AGE_MIN` | `60` | порог возраста (мин); **обязан** > `max(merge_retest_timeout_s=600, coverage_run_timeout_s=900)/60` |
|
||
| `WATCHDOG_PROC_PATTERNS` | `pytest` | CSV паттернов cmdline (substring-матч) |
|
||
| `WATCHDOG_PROC_COOLDOWN_S` | `1800` | per-signal cooldown |
|
||
- **Канон тиража (NFR-5 / AC-10):** ключи добавить в **том же PR** в `.env.watchdog.example` **И** в
|
||
блок `WATCHDOG_*` `.env.example` (равенство множеств держит `tests/test_lite_setup_doc.py`
|
||
TC-02b) + описать в `docs/deployment/LITE_SETUP.md` и `docs/architecture/README.md`.
|
||
- **Секреты:** новых нет. Канал алертов — существующий `WATCHDOG_TG_*` (свой бот sidecar, C-1).
|
||
- **На прод-хосте (разово, человек):** в `.env.watchdog` выставить `WATCHDOG_PROC_ENABLED=true`
|
||
(включение сигнала; без этого — дремлет).
|
||
|
||
## I-3. Деплой / рестарт
|
||
- **Self-hosting инвариант (NFR-3):** выкат пересобирает/рестартит **только** контейнер
|
||
`orchestrator-watchdog` (`docker compose up -d --build orchestrator-watchdog`). Прод-контейнер
|
||
`orchestrator` **НЕ** перезапускается (иначе встанет конвейер всех проектов, включая enduro).
|
||
- Прод-выкат sidecar — через staging-эквивалент (smoke на staging-хосте перед прод): проверить, что
|
||
под `pid: host` коллектор видит процессы, сигнал поднимается на синтетическом старом pytest и молчит
|
||
при дефолт-off.
|
||
- **Откат:** `WATCHDOG_PROC_ENABLED=false` (мгновенный; привилегия дремлет) либо снятие `pid: host` +
|
||
рестарт только sidecar.
|
||
|
||
## I-4. CI/CD
|
||
- Без изменений `.gitea/workflows/`. Новые тесты — `tests/watchdog/test_proc_blocking_signal.py`,
|
||
`tests/watchdog/test_tick_proc_blocking_integration.py` (TRZ §2) — исполняются существующим
|
||
`pytest tests/`. Key-sync (`test_lite_setup_doc.py`) и compose-тесты watchdog должны остаться
|
||
зелёными.
|
||
</content>
|