- docs/ai/: stable, repo-verified context - README, architecture, tech-stack, edge-cases, plan (confirmed active work only), migration-tofu (the blue-green OpenTofu migration runbook and per-service findings), legacy-warning, links. - AGENTS.md: slimmed to a working contract that points at docs/ai instead of restating it; CLAUDE.md is an adapter that @-includes it. - README.md, ansible/README.md, ansible/roles/README.md, roles/lxc_docker_host/README.md: bring wording in line with the current control plane (Makefile entry point, registry, tofu, memoir-bot gone). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012uoq5AVK8mkBgg83Mq6o5V
143 lines
7.4 KiB
Markdown
143 lines
7.4 KiB
Markdown
# Архитектура
|
||
|
||
## Контекст и точки входа
|
||
|
||
Репозиторий является control plane, а не приложением с единым runtime. Оператор
|
||
запускает цели `ansible/Makefile`; Make загружает локальные secrets, применяет safety
|
||
gates и вызывает playbooks. `ansible.cfg` выбирает inventory, roles и локально
|
||
установленные Galaxy collections.
|
||
|
||
Канонические источники:
|
||
|
||
- хосты и группы: `ansible/inventory/hosts.yml`;
|
||
- общий доступ и сеть: `ansible/inventory/group_vars/all/main.yml`;
|
||
- сводные сведения о сервисах: `ansible/inventory/group_vars/all/services.yml`;
|
||
- SSH transport: `ansible/ssh_config`;
|
||
- ручные операции: `ansible/Makefile`.
|
||
|
||
Программные потребители реестра:
|
||
|
||
- `playbooks/reverse-proxy.yml` — сборка Caddyfile;
|
||
- `playbooks/ru-vps-base.yml` — стек Caddy и его закреплённый образ;
|
||
- `playbooks/pve-backup-jobs.yml` — списки VMID заданий PBS (поле `backup.job`);
|
||
- `roles/backup_audit` — VMID для аудита (флаг `monitoring.backup_audit_vmid`);
|
||
- `playbooks/validate.yml` — сверка реестра с фактическим состоянием Proxmox.
|
||
|
||
Остальное (`pve-*.yml`, `status.yml`, monitoring, SSH config) по-прежнему
|
||
дублирует значения и должно меняться согласованно.
|
||
|
||
## Топология
|
||
|
||
- `ru-vps`: public VPS, qdevice, Caddy, OpenVPN server и SSH JumpHost.
|
||
- `cloud-pc`, `mini-pc`: Proxmox VE nodes.
|
||
- `lxc_infra`: PBS, OpenVPN gateway и service LXC.
|
||
- `monitoring`: CT 146 на `cloud-pc`; Uptime Kuma активен, Prometheus stack заморожен.
|
||
|
||
Актуальные VMID, placement, IP, ports, domains и backup policy не копируются сюда:
|
||
их нужно читать из `homelab_services` и сверять с `hosts.yml`.
|
||
|
||
## Provisioning Flow
|
||
|
||
1. `make deploy-<service>` загружает ignored `.env` из корня репозитория.
|
||
2. `playbooks/pve-<service>.yml` создает или сверяет LXC.
|
||
3. Часть playbooks вызывает `roles/pve_lxc` через Proxmox API.
|
||
4. Остальные подключаются по SSH к PVE node и выполняют `pct create/set/start`.
|
||
5. Следующий play настраивает LXC, runtime, systemd и health checks.
|
||
|
||
Два provisioner-пути имеют разные check-mode и ownership guards. Нельзя переносить
|
||
service между ними как косметический рефакторинг.
|
||
|
||
## Service Runtime
|
||
|
||
- Большинство сервисов используют systemd units вокруг `docker run`.
|
||
- Grimmory использует Compose и отдельный `DOCKER-USER` firewall unit.
|
||
- Uptime Kuma и сохраненный monitoring stack используют legacy `docker-compose`.
|
||
- `lxc_docker_host` и `compose_service` описывают будущий общий паттерн, но ни один
|
||
production playbook их пока не вызывает.
|
||
|
||
## Network Flow
|
||
|
||
`ansible_ssh_common_args` подключает `ansible/ssh_config`. Обычный путь управления:
|
||
|
||
```text
|
||
controller -> ru-vps:3422 -> 192.168.1.x target
|
||
```
|
||
|
||
`pbs` и `ovpn-mini` являются direct-LAN исключениями. LXC обычно управляются как
|
||
`root`, а PVE nodes и `ru-vps` - как service account `ansible`.
|
||
|
||
OpenVPN site tunnel:
|
||
|
||
```text
|
||
ru-vps 10.78.0.1:8443/tcp <-> ovpn-mini 10.78.0.2 -> 192.168.1.0/24
|
||
```
|
||
|
||
Публичный service flow:
|
||
|
||
```text
|
||
Internet -> Caddy on ru-vps -> OpenVPN -> ovpn-mini -> LAN service
|
||
```
|
||
|
||
Потеря `ru-vps` или site tunnel одновременно влияет на public upstreams и обычный
|
||
SSH management path.
|
||
|
||
## Reverse Proxy
|
||
|
||
`playbooks/reverse-proxy.yml` выбирает записи `homelab_services` с блоком `proxy`,
|
||
валидирует metadata и Caddyfile, обновляет marked blocks и проверяет upstreams.
|
||
Ansible управляет Caddyfile, но не установкой и lifecycle контейнера Caddy на `ru-vps`.
|
||
Grimmory OPDS/KOReader routes имеют специальные headers и отключение compression;
|
||
их нельзя упрощать без device compatibility tests.
|
||
|
||
## Backup и Update
|
||
|
||
`playbooks/pve-backup-jobs.yml` задает cluster-level PBS schedules. Offsite restic
|
||
profiles выполняются systemd timers и используют application-aware SQLite backup или
|
||
MariaDB dump. `roles/backup_audit` проверяет freshness, `restic check` и выборочные
|
||
restores, после чего атомарно пишет textfile metrics.
|
||
|
||
Update playbooks выполняют:
|
||
|
||
```text
|
||
fresh backup/audit -> reapply service declaration -> health verification
|
||
```
|
||
|
||
Backup является prerequisite для ручного recovery, а не автоматическим rollback.
|
||
|
||
## Monitoring
|
||
|
||
Uptime Kuma в CT 146 является активным monitoring UI. Его роль останавливает и
|
||
отключает `homelab-monitoring`, сохраняя конфигурацию и данные Prometheus stack.
|
||
`make monitoring` защищен `CONFIRM=1` и предназначен только для отдельно принятого
|
||
решения о восстановлении старого stack.
|
||
|
||
Exporter roles, groups и backup metrics остаются в репозитории. Hardcoded Prometheus
|
||
targets могут расходиться с inventory, пока stack заморожен.
|
||
|
||
## Grimmory MCP
|
||
|
||
`tools/grimmory-mcp/src/server.js` запускает локальный stdio MCP. Grimmory API
|
||
используется read-only; authentication POST не меняет library data. Явно вызванные
|
||
sync tools читают API, опционально загружают cover, атомарно обновляют managed sections
|
||
Obsidian notes и запускают внешний vault index script.
|
||
|
||
Sync не является общей транзакцией: full sync может закончиться после частичного
|
||
набора успешных book updates. Vault path и credential file защищены отдельными
|
||
проверками, описанными в [`edge-cases.md`](edge-cases.md).
|
||
|
||
## Testing Boundaries
|
||
|
||
- Ansible имеет static lint и syntax checks, но не имеет Molecule/idempotence harness.
|
||
- `check.yml` проверяет reachability и expected IP, а не service health.
|
||
- `status.yml` формирует наблюдательный отчет и не является failing health gate.
|
||
- Grimmory MCP имеет Node test suite.
|
||
- Gitea Actions workflow существует, но runner и Actions не активированы.
|
||
|
||
## Неизвестно
|
||
|
||
- Текущие runtime versions Proxmox VE, OpenVPN, Caddy и restic не закреплены repo manifests.
|
||
- UI-only состояние AdGuard, Uptime Kuma monitors и часть service credentials не может
|
||
быть установлена из репозитория.
|
||
- Наличие DHCP reservation для Grimmory и намеренность отсутствия backup CT 148
|
||
требуют проверки оператором.
|