Files

14 KiB
Raw Permalink Blame History

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.gc vs 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).