14 KiB
work_item, stage, author_agent, status, created_at, model_used
| work_item | stage | author_agent | status | created_at | model_used |
|---|---|---|---|---|---|
| ORCH-062 | analysis | analyst | ready-for-review | 2026-06-09 | claude-opus-4-8 |
01 — BRD (бизнес-требования): ORCH-062 — INFRA: авто-prune docker build cache на mva154
Work Item: ORCH-062 · Repo: orchestrator · Стадия: analysis
1. Бизнес-контекст и проблема
Установленный факт (инцидент 07.06.2026). Хост-диск mva154 тихо дорос до 100% и положил
весь конвейер всех проектов (один прод-инстанс orchestrator на общей БД/очереди обслуживает
и enduro-trails, и orchestrator). Доминирующий «пожиратель» в этом инциденте — docker build
cache: частые пересборки образа (docker compose up -d --build при прод-деплое, пересборки
staging-образа --profile staging и check_staging_image_fresh ORCH-058) накапливают слои build
cache, который дорос до ≈11 ГБ. Заполнение диска положило CI + Gitea и остановило приём
вебхуков/обработку очереди.
Что уже сделано (ORCH-063, не дублировать). Введён фоновый daemon src/disk_watchdog.py,
который только сигнализирует (Telegram-алерт при заполнении ≥85%). В ADR/INFRA ORCH-063 явно
зафиксировано: «watchdog только сигнализирует — он не трогает диск/контейнер … Авто-очистка — вне
объёма ORCH-063 (отдельная задача)». ORCH-062 — и есть эта отдельная задача: автоматическое
освобождение места за счёт build cache, чтобы инцидент 07.06 не повторялся и не требовал ручного
вмешательства оператора.
Приоритет: P1 (риск повторной полной остановки конвейера всех проектов).
2. Объём (scope)
В объёме
- Автоматическое периодическое освобождение docker build cache на хосте mva154, чтобы он не мог бесконтрольно дорасти до заполнения диска.
- Удержание «тёплого» недавнего кэша (политика хранения по возрасту, ориентир из запроса —
until=24h), чтобы не убивать скорость штатных пересборок. - Наблюдаемость результата авто-prune для оператора (когда последний раз отработал, сколько освобождено / текущий объём build cache).
- Обратимость: kill-switch и конфигурируемость периода/порога/политики хранения.
- Документирование операционной процедуры в
docs/operations/INFRA.md(и инфра-требований в07-infra-requirements.md— заполняет архитектор).
Вне объёма
- Очистка прочих «пожирателей» диска (старые worktree-каталоги
/home/slin/repos/_wt/*завершённых задач, логи, dangling-образыdocker image prune) — это ручная операция оператора по ORCH-063; авто-уборка этих категорий — отдельные задачи, здесь НЕ делается. - Изменение поведения disk-watchdog (
src/disk_watchdog.py, пороги/алерты ORCH-063) — не трогаем; ORCH-062 ортогонален и комплементарен (watchdog сигналит, pruner убирает). - Любое управление конвейером / стадиями / Quality Gates. Авто-prune — операционная фоновая
задача, НЕ элемент
STAGE_TRANSITIONS/QG_CHECKS(ровно как watchdog/reconciler/job_reaper). - Перезапуск/рестарт прод-контейнера
orchestratorради уборки — категорически вне объёма (self-hosting групповой риск). - Выбор между конкретными механизмами реализации (heartbeat-демон в приложении vs host
daemon.json builder.gcvs host-cron) — это архитектурное решение (06-adr), не предмет BRD.
3. Заинтересованные стороны
- Owner / оператор (slin, homenet542@gmail.com) — заказчик, принимает результат, владеет хостом mva154 и его host-prerequisites.
- Все прод-проекты (
enduro-trails,orchestrator) — косвенно затронуты: общий инстанс, общий диск; падение диска = простой всех. - Self-hosting контур — изменение касается инструмента, который работает в проде и обслуживает другие проекты; безопасность изменения критична.
4. Бизнес-требования (BR)
- BR-1 (авто-освобождение) — docker build cache очищается автоматически, периодически, без ручного вмешательства оператора, так что он не может бесконтрольно заполнить диск (устранение корня инцидента 07.06).
- BR-2 (удержание тёплого кэша) — очистка удаляет преимущественно старый build cache
(политика по возрасту, ориентир
until=24h); свежий кэш недавних сборок сохраняется, чтобы штатные пересборки не теряли скорость без необходимости. - BR-3 (self-hosting безопасность) — операция уборки никогда не нарушает работу запущенных
контейнеров и не удаляет образы/слои, используемые работающими прод-контейнерами, и никогда
не рестартит/не роняет прод. Затрагивается только build cache (
docker builder prune), не образы запущенных сервисов. - BR-4 (наблюдаемость) — оператор может увидеть состояние авто-prune: включён ли, когда
последний раз отработал, объём/освобождено (через тот же канал наблюдаемости, что у фоновых
демонов — блок в
GET /queue, и/или Telegram при значимом освобождении). - BR-5 (обратимость) — поведение управляется kill-switch: выключение возвращает систему к
поведению «как сейчас» 1:1 (никакой авто-уборки), как у
ORCH_DISK_MONITOR_ENABLED/ORCH_RECONCILE_ENABLED. - BR-6 (конфигурируемость) — период, порог запуска и политика хранения (возраст/объём удержания) задаются конфигом (env), с безопасными дефолтами; невалидные значения деградируют на дефолт (как валидаторы ORCH-063).
5. Нефункциональные требования (NFR)
- NFR-1 (never-raise) — фоновая уборка не должна ронять процесс/конвейер ни на одном уровне:
ошибка docker-команды / недоступность docker.sock / таймаут логируются и проглатываются (как
per-tick/per-send never-raise в
disk_watchdog.py). - NFR-2 (изоляция от Quality Gate) —
STAGE_TRANSITIONS/QG_CHECKS/check_*/ схема БД не изменяются; авто-prune — операционный демон/процедура, не гейт. - NFR-3 (нулевая регрессия при выключении) — при выключенном kill-switch поведение байт-в-байт как до задачи; никакого фонового потока/процедуры не стартует.
- NFR-4 (низкий оверхед) — частота уборки — порядка часов; сама команда
docker builder pruneдешева и не должна влиять на латентность конвейера; уборка не должна конкурировать за ресурсы с активными сборками сверх необходимого. - NFR-5 (best-effort состояние) — учёт «когда убирали в последний раз» может быть in-memory / best-effort (как анти-спам watchdog'а): сброс при рестарте безопасен (приведёт максимум к одной лишней безопасной уборке), без новой миграции БД.
- NFR-6 (документируемость) — операционная процедура, env-переменные и поведение при сбое
зафиксированы в
docs/operations/INFRA.mdи.env.exampleв том же PR (golden source = код+доки).
6. Допущения и ограничения
- A-1. У контейнера
orchestratorесть доступ к/var/run/docker.sock(черезgroup_add: ["999"], gid docker — НЕ удалять, ORCH-040), что технически позволяет приложению вызыватьdocker builder prune. Это не предрешает выбор реализации (демон в приложении vs host-уровень). - A-2.
docker builder pruneпо контракту docker затрагивает только build cache, не останавливает контейнеры и не удаляет образы запущенных сервисов — это основа безопасности BR-3. - A-3. Доминирующий «пожиратель» в инциденте — именно build cache (≈11 ГБ); прочие категории (worktree/логи/dangling-образы) адресуются отдельно (см. Вне объёма).
- A-4. Хост — mva154 (
network_mode: host), uid рантайма 1000:1000; любые host-prerequisites (например, права на docker.sock, настройкаdaemon.jsonесли выбран этот путь) — процедура Owner, в git не коммитятся (по аналогии с P-1…P-4 в INFRA.md). - Ограничение C-1. Нельзя рестартить docker daemon в рабочее время без окна тишины, если
выбранный архитектором путь (
daemon.json builder.gc) требует перезапуска демона — это решает и планирует архитектор/Owner (вне объёма кода).
7. Критерии успеха
- Build cache на mva154 удерживается в безопасных пределах автоматически: после внедрения повторение сценария 07.06 (build cache → 11 ГБ → диск 100%) предотвращается без ручных действий.
- Свежие сборки не теряют скорость без необходимости (тёплый кэш ≤ политики хранения сохраняется).
- Запущенные прод-контейнеры и обслуживание
enduro-trailsне затронуты; прод не рестартился. - Оператор видит состояние авто-prune и может его выключить одним флагом.
- Детальные PASS/FAIL — в
03-acceptance-criteria.md.
8. Риски
Краткий перечень (детальная проработка — 10-tech-risks.md, заполняет архитектор):
- R-1. Слишком агрессивная политика (
-aбез возрастного фильтра / малыйuntil) убивает тёплый кэш → каждая сборка «холодная» и медленная. Митигирует BR-2 (удержание по возрасту). - R-2. Гонка уборки с активной сборкой staging/прод-образа (
check_staging_image_fresh, build-once retag) → теоретически удаление кэша во время сборки.docker builder pruneштатно не трогает кэш, занятый активной сборкой, но политику/таймиг проверить (адресует архитектор). - R-3. Реализация через host-
daemon.jsonтребует рестарта docker daemon → риск для self-hosting; реализация через демон в приложении требует доступа к docker.sock и устойчивости к его недоступности. - R-4. Ошибочное расширение скоупа на
docker image prune/system prune→ удаление образов запущенных контейнеров. Жёстко исключено BR-3 (только build cache).