Add DetMir primary recovery guard

This commit is contained in:
igor04091968
2026-07-03 08:51:11 +03:00
parent 130d4cd94f
commit 08c67bde1a
7 changed files with 672 additions and 2 deletions
+18 -1
View File
@@ -1,6 +1,6 @@
# Ежедневное обслуживание AWatch-rus
Дата актуализации: 2026-07-02
Дата актуализации: 2026-07-03
Документ описывает ежедневный операторский цикл обслуживания AWatch-rus /
DetMir и безопасное использование Pollinations AI как вспомогательного
@@ -87,6 +87,22 @@ node scripts/deployment-readiness-smoke.mjs
Критерий: нет новых hard-fail проверок. Warning допустим только при известном
и задокументированном operational constraint.
### 3.1. Primary recovery guard
Проверить, что автоматический recovery первичного AW API включен и не скрывает
новые incident:
```bash
systemctl is-active detmir-aw-primary-recovery.timer
systemctl status detmir-aw-primary-recovery.timer --no-pager
sudo /usr/local/bin/detmir-aw-primary-recovery --check-only
sudo jq . /var/lib/detmir-aw-primary-recovery/latest.json 2>/dev/null || true
```
Критерий: timer активен, `--check-only` возвращает `status=ok`, новые incident
не имеют `outcome=failed`. Если latest incident отсутствует, это нормально для
контура, где recovery еще ни разу не требовался.
### 4. Очереди, backlog и storage growth
Проверить отсутствие неконтролируемого роста:
@@ -305,6 +321,7 @@ unset ALL_PROXY all_proxy
- [Operations Runbook](OPERATIONS_RUNBOOK_RU.md)
- [Эксплуатационная проверка контура](OPERATIONS_VALIDATION_RUNBOOK_RU.md)
- [DetMir service reliability runbook](DETMIR_SERVICE_RELIABILITY_RUNBOOK_RU.md)
- [Retention and Cleanup Policy](RETENTION_POLICY_RU.md)
- [Production readiness](PRODUCTION_READINESS_RU.md)
- [Autonomous validation](AUTONOMOUS_VALIDATION_RU.md)
@@ -0,0 +1,233 @@
# DetMir Service Reliability Runbook
Дата актуализации: 2026-07-03
Документ описывает production-safe контур снижения повторных выпадений сервисов
AWatch-rus/DetMir. Главная цель — отделять первичный отказ ActivityWatch API от
вторичных падений ingest/report/health jobs и выполнять ограниченное
автовосстановление только для подтвержденного безопасного сценария.
## План реализации
1. Считать `activitywatch-server` первичным сервисом для AW API.
2. Считать `aw-workforce-ingest`, `aw-worktime-autoheal`, `aw-worktime-prewarm`,
`aw-worktime-ui-bridge`, `aw-worktime-influx-exporter`, `aw-rus-healthd` и
`aw-slo-monitor` вторичными зависимыми jobs.
3. Проверять AW API через `/api/0/settings/` и `/api/0/buckets/`.
4. Автоматически восстанавливать только подтвержденный класс отказа:
`poisoned datastore lock` или неактивный `activitywatch-server`.
5. Перед restart первичного сервиса временно остановить вторичные jobs, чтобы
они не усиливали нагрузку на AW SQLite.
6. Перезапустить только `activitywatch-server` внутри CT `203`.
7. Дождаться восстановления AW API.
8. Вернуть вторичные timers и записать incident JSON.
## Что реализовано
Реализован script:
```text
scripts/detmir-aw-primary-recovery.sh
```
Systemd units для Proxmox host:
```text
ops/systemd/detmir-aw-primary-recovery.service
ops/systemd/detmir-aw-primary-recovery.timer
```
Контур предназначен для запуска на Proxmox host `10.10.10.2`, потому что там
доступны одновременно:
- управление PVE jobs через локальный `systemctl`;
- управление AW CT через `pct exec 203`;
- проверка внешнего AW API `http://10.10.10.13:5600`.
## Safety Rules
Recovery script:
- не удаляет SQLite database, lock files или journal files;
- не включает DLP, Loki или always-on Velociraptor;
- не перезапускает Windows host и Windows collectors;
- не меняет конфигурацию AW server;
- не выполняет recovery при произвольном HTTP timeout без подтвержденной
причины;
- имеет cooldown между restart попытками;
- пишет incident evidence в JSON.
## Установка
На Proxmox host:
```bash
sudo install -m 0755 scripts/detmir-aw-primary-recovery.sh \
/usr/local/bin/detmir-aw-primary-recovery
sudo install -m 0644 ops/systemd/detmir-aw-primary-recovery.service \
/etc/systemd/system/detmir-aw-primary-recovery.service
sudo install -m 0644 ops/systemd/detmir-aw-primary-recovery.timer \
/etc/systemd/system/detmir-aw-primary-recovery.timer
sudo systemctl daemon-reload
sudo systemctl enable --now detmir-aw-primary-recovery.timer
```
Опциональная конфигурация:
```bash
sudo install -d -m 0755 /etc/detmir
sudoedit /etc/detmir/aw-primary-recovery.env
```
Пример:
```bash
DETMIR_AW_RECOVERY_URL=http://10.10.10.13:5600
DETMIR_AW_RECOVERY_CT_ID=203
DETMIR_AW_RECOVERY_CONFIRM_ATTEMPTS=2
DETMIR_AW_RECOVERY_COOLDOWN_SECONDS=900
DETMIR_AW_RECOVERY_HTTP_TIMEOUT_SECONDS=8
```
## Проверка без изменений
```bash
/usr/local/bin/detmir-aw-primary-recovery --self-test
/usr/local/bin/detmir-aw-primary-recovery --check-only
systemctl start detmir-aw-primary-recovery.service
journalctl -u detmir-aw-primary-recovery.service -n 80 --no-pager
```
Ожидаемо для здорового контура:
```text
event=probe attempt=1 status=ok
```
## Evidence
Incident files:
```text
/var/lib/detmir-aw-primary-recovery/incidents/*.json
/var/lib/detmir-aw-primary-recovery/latest.json
/var/lib/detmir-aw-primary-recovery/status.json
```
Проверка последнего incident:
```bash
sudo jq . /var/lib/detmir-aw-primary-recovery/latest.json
```
Ключевые поля:
- `outcome`: `recovered`, `failed`, `skipped`, `observed_no_action`, `dry_run`;
- `reason`: `poisoned_lock`, `service_inactive`, `cooldown_active_after_*`;
- `recovered`: boolean;
- `pve_pause_units`;
- `ct_pause_units`;
- `details`.
## Rollback
Отключить automation:
```bash
sudo systemctl disable --now detmir-aw-primary-recovery.timer
sudo systemctl reset-failed detmir-aw-primary-recovery.service
```
Удаление установленных файлов не требуется для rollback. Если нужно убрать
полностью:
```bash
sudo rm -f /etc/systemd/system/detmir-aw-primary-recovery.service
sudo rm -f /etc/systemd/system/detmir-aw-primary-recovery.timer
sudo rm -f /usr/local/bin/detmir-aw-primary-recovery
sudo systemctl daemon-reload
```
## Manual Recovery Sequence
Если automation disabled или recovery не помог:
```bash
sudo systemctl stop aw-workforce-ingest.timer aw-workforce-ingest.service
sudo pct exec 203 -- systemctl stop \
aw-worktime-autoheal.timer aw-worktime-autoheal.service \
aw-worktime-prewarm.timer aw-worktime-prewarm.service \
aw-worktime-ui-bridge.timer aw-worktime-ui-bridge.service \
aw-worktime-influx-exporter.timer aw-worktime-influx-exporter.service \
aw-rus-healthd.timer aw-rus-healthd.service \
aw-slo-monitor.timer aw-slo-monitor.service
sudo pct exec 203 -- systemctl restart activitywatch-server
curl -fsS http://10.10.10.13:5600/api/0/settings/ >/dev/null
curl -fsS http://10.10.10.13:5600/api/0/buckets/ >/dev/null
sudo pct exec 203 -- systemctl start \
aw-worktime-autoheal.timer \
aw-worktime-prewarm.timer \
aw-worktime-ui-bridge.timer \
aw-worktime-influx-exporter.timer \
aw-rus-healthd.timer \
aw-slo-monitor.timer
sudo systemctl start aw-workforce-ingest.timer
```
## Post-Recovery Validation
```bash
cd /mnt/usb_hdd2/Projects/ActivityWatch-Russian
./check-aw-full.sh
ssh igor@10.10.10.2 'systemctl --failed --no-legend || true'
ssh igor@10.10.10.2 'sudo pct exec 203 -- systemctl --failed --no-legend || true'
curl -fsS http://10.10.10.13:5610/health | jq .
curl -fsS http://10.10.10.2:8720/readyz | jq .
```
Критерий:
- `check-aw-full.sh`: `DEAD=0`, `STALE=0`;
- failed units на Proxmox host: `0`;
- failed units внутри CT `203`: `0`;
- Worktime health: `status=OK`;
- Portal readiness: `status=ready`.
## Gateway Contract
Операторские shortcuts должны соответствовать runbook:
```text
/go/proxmox-gui
/go/file1c-brief
/go/file1c-actions
```
Они формируются из `proxmox_web_gateway_routes` в nginx template и должны
возвращать `302` на целевой внутренний URL после Basic Auth.
Readiness compatibility endpoint:
```text
/portal/api/readiness -> http://127.0.0.1:8720/readyz
```
## Known Limitations
- Recovery intentionally limited to AW API poisoned lock and inactive primary
service. Other failures remain operator-visible incidents.
- If restart does not restore AW API before timeout, secondary timers remain
paused to avoid failure amplification. Operator must inspect
`/var/lib/detmir-aw-primary-recovery/latest.json`.
- Windows credential or WinRM authentication problems are outside this recovery
loop.
- This does not prove backup/restore. It is runtime availability recovery only.
+18
View File
@@ -6,6 +6,10 @@
использование Pollinations AI для анализа sanitized evidence описаны отдельно:
[ежедневное обслуживание AWatch-rus](DAILY_MAINTENANCE_RU.md).
Автоматическое восстановление первичного AW API от подтвержденного
`poisoned datastore lock` описано отдельно:
[DetMir service reliability runbook](DETMIR_SERVICE_RELIABILITY_RUNBOOK_RU.md).
## Быстрая проверка
Проверить доступность:
@@ -108,6 +112,20 @@ systemctl --failed --no-pager
- coverage;
- errors in logs.
### ActivityWatch API возвращает `503 poisoned lock`
Проверить, сработал ли primary recovery guard:
```bash
systemctl status detmir-aw-primary-recovery.timer --no-pager
journalctl -u detmir-aw-primary-recovery.service -n 80 --no-pager
sudo jq . /var/lib/detmir-aw-primary-recovery/latest.json
```
Если guard отключен, использовать manual sequence из
`DETMIR_SERVICE_RELIABILITY_RUNBOOK_RU.md`. Не удалять SQLite, lock или journal
файлы ActivityWatch вручную.
### Нет данных
Проверить: