lint / yamllint + ansible-lint + syntax-check (push) Canceled after 0s
playbooks/dashboard.yml deploys Homepage as a second compose stack on the monitoring LXC (CT 155) next to Uptime Kuma and renders its config from homelab_services: one tile per service, link to its UI, grouped by Proxmox node. Adding a service to the registry is enough — no second service list. - new registry consumer: playbooks/dashboard.yml + playbooks/templates/homepage-*.j2 - homelab_dashboard_* vars in group_vars/all/services.yml (top-level, like homelab_reverse_proxy_*); image pinned by digest, floating tag needs an explicit -e dashboard_allow_floating_tag=true - bootstrap-dashboard-pve-token.yml: read-only homepage@pve!dashboard token (PVEAuditor) for the Proxmox widget, secret in the root .env as DASHBOARD_PVE_* - Makefile: dashboard, dry-dashboard, bootstrap-dashboard-token - container binds the LAN address only (192.168.1.30:8082), not published via Caddy - docs: architecture.md Monitoring section, plan.md active task, consumer lists Deployed to CT 155 on 2026-09-03: container healthy, http://192.168.1.30:8082/ returns 200, `make dashboard` idempotent, `make validate` and `make lint` green. Pending operator steps: `make bootstrap-dashboard-token` (blocked in the agent session as credential creation) and an Uptime Kuma status page with slug homelab. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KbuZrUoevfBgCpf5DCF4DG
156 lines
9.3 KiB
Markdown
156 lines
9.3 KiB
Markdown
# AGENTS.md
|
||
|
||
## Назначение
|
||
|
||
HomeLab infras - Ansible-first control plane для домашней инфраструктуры на
|
||
Proxmox VE. Желаемое состояние хранится в inventory, vars, roles и playbooks;
|
||
прямые изменения на серверах допустимы только для read-only диагностики или
|
||
break-glass восстановления и затем должны быть отражены в Ansible.
|
||
|
||
Стабильный контекст проекта находится в [`docs/ai/`](docs/ai/README.md). Не
|
||
загружай весь набор по умолчанию: читай только документы, относящиеся к задаче.
|
||
|
||
## Что читать
|
||
|
||
| Задача | Контекст |
|
||
|---|---|
|
||
| Любое изменение | `README.md`, [`docs/ai/README.md`](docs/ai/README.md), релевантная секция [`architecture.md`](docs/ai/architecture.md) |
|
||
| Inventory или новый service | `ansible/inventory/hosts.yml`, `ansible/inventory/group_vars/all/services.yml`, [`architecture.md`](docs/ai/architecture.md), [`edge-cases.md`](docs/ai/edge-cases.md) |
|
||
| Provisioning или update | `ansible/README.md`, relevant playbook/role, [`edge-cases.md`](docs/ai/edge-cases.md), [`legacy-warning.md`](docs/ai/legacy-warning.md) |
|
||
| Network, SSH, OpenVPN, Caddy | `ansible/ssh_config`, `ansible/inventory/group_vars/all/main.yml`, [`architecture.md`](docs/ai/architecture.md), [`links.md`](docs/ai/links.md) |
|
||
| Backups и recovery | `ansible/playbooks/pve-backup-jobs.yml`, `ansible/roles/backup_audit/`, [`architecture.md`](docs/ai/architecture.md), [`edge-cases.md`](docs/ai/edge-cases.md) |
|
||
| Grimmory MCP | `tools/grimmory-mcp/README.md`, [`tech-stack.md`](docs/ai/tech-stack.md), [`edge-cases.md`](docs/ai/edge-cases.md) |
|
||
| Legacy/frozen code | [`legacy-warning.md`](docs/ai/legacy-warning.md) |
|
||
| Переезд на OpenTofu | [`migration-tofu.md`](docs/ai/migration-tofu.md), `tofu/README.md`, `tofu/*.tf` |
|
||
| Текущая работа | [`plan.md`](docs/ai/plan.md); `current-task.md` является историческим планом |
|
||
|
||
Перед инфраструктурными изменениями прочитай релевантные заметки в Obsidian:
|
||
|
||
`/home/ada/Documents/Vaults/SecondBrain/02 Projects/HomeLab/`
|
||
|
||
Основные заметки: `HomeLab.md`,
|
||
`Notes/Текущее состояние HomeLab после миграции на Proxmox.md`, `Log.md`.
|
||
После изменения обнови соответствующую заметку, если изменились topology,
|
||
операционная процедура, решение или неочевидное ограничение.
|
||
|
||
## Источники правды
|
||
|
||
- Hosts и groups: `ansible/inventory/hosts.yml`.
|
||
- Shared network/access vars: `ansible/inventory/group_vars/all/main.yml`.
|
||
- Service facts: `ansible/inventory/group_vars/all/services.yml`.
|
||
- SSH users, keys, ports и ProxyJump: `ansible/ssh_config`.
|
||
- Manual operations и safety gates: `ansible/Makefile`.
|
||
- Secrets: ignored `.env` в КОРНЕ репозитория; его читают и Make/Ansible, и OpenTofu.
|
||
- Human decisions и operations log: HomeLab Obsidian vault.
|
||
|
||
Программные потребители реестра:
|
||
|
||
- `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;
|
||
- `playbooks/dashboard.yml` — `services.yaml` для Homepage-обзора инфраструктуры.
|
||
|
||
Остальное (`pve-*.yml`, `status.yml`, monitoring, SSH config) по-прежнему
|
||
дублирует значения и должно меняться согласованно.
|
||
|
||
`make validate` — read-only gate, проверяющий это расхождение.
|
||
|
||
## Границы
|
||
|
||
- Active control plane находится в `ansible/`.
|
||
- `archive/2026-07-proxmox-migration/` - только историческая справка; не редактировать
|
||
и не возвращать из него конфигурацию как active implementation.
|
||
- Не редактировать generated artifacts, `ansible/collections/`, `.venv/`,
|
||
`node_modules/`, `.direnv/` и secret-bearing ignored files.
|
||
- `roles/compose_service` подключён в `playbooks/ru-vps-base.yml` (стек Caddy).
|
||
`roles/lxc_docker_host` не подключён нигде.
|
||
Не считать active service playbooks устаревшими до отдельной миграции.
|
||
- Не исправлять найденный technical debt в несвязанной задаче без отдельного решения.
|
||
- Для новой VM/LXC/managed host по умолчанию provision public SSH key пользователя,
|
||
если пользователь явно не указал иное.
|
||
|
||
## Setup и команды
|
||
|
||
Предпочтительное окружение - Nix:
|
||
|
||
```bash
|
||
nix develop # или один раз: direnv allow
|
||
ansible-galaxy collection install \
|
||
-r ansible/requirements.yml \
|
||
-p ansible/collections # один раз на clone
|
||
```
|
||
|
||
Работай через Make из `ansible/` или с `make -C ansible` из root:
|
||
|
||
```bash
|
||
make -C ansible help
|
||
make -C ansible check
|
||
make -C ansible status EXTRA="--limit '!gyro'"
|
||
make -C ansible inventory
|
||
make -C ansible docs
|
||
make -C ansible lint
|
||
```
|
||
|
||
Локальный syntax-check всех playbooks, соответствующий CI:
|
||
|
||
```bash
|
||
nix develop -c sh -c \
|
||
'cd ansible && for f in playbooks/*.yml; do ansible-playbook --syntax-check "$f"; done'
|
||
```
|
||
|
||
Grimmory MCP требует отдельный Node.js `>=22` runtime:
|
||
|
||
```bash
|
||
npm install --prefix tools/grimmory-mcp
|
||
npm test --prefix tools/grimmory-mcp
|
||
```
|
||
|
||
## Safety Contract
|
||
|
||
- Сначала выполняй smallest safe local validation, затем bounded live check только
|
||
когда он нужен задаче.
|
||
- `make dry-<service>` использует `--check --diff`, но не является полной симуляцией
|
||
Proxmox API или command-heavy `pct` playbooks.
|
||
- `make status` read-only, но его exit code не является health gate.
|
||
- `update-all`, `mihomo-harden` и frozen `monitoring` требуют `CONFIRM=1`.
|
||
- `gyro` требует Vault password; не обходи `make gyro` без явной причины.
|
||
- Service update order: fresh backup/audit -> update -> health check. Backup не
|
||
означает automatic rollback.
|
||
- Uptime Kuma активен. Prometheus/Alertmanager/Grafana stack заморожен; не запускать
|
||
его параллельно без отдельного architecture decision.
|
||
- Active remote images обычно pin по `tag@sha256:digest`; frozen Prometheus images
|
||
tag-only. Floating auto-updaters не используются.
|
||
- Не включать cluster-wide PVE firewall без аудита всех guests с `firewall=1`.
|
||
- Не останавливать production services для fault injection без согласованного
|
||
maintenance window.
|
||
|
||
## Secrets
|
||
|
||
- Никогда не коммить и не цитировать реальные passwords, tokens, private keys,
|
||
`.env`, Vault plaintext, PBS/restic credentials или TLS keys.
|
||
- Используй ignored `.env` в корне репозитория, Ansible Vault, runtime prompt или
|
||
external local secret file.
|
||
- `PROXMOX_ROOT_PASSWORD` (root@pam) нужен ТОЛЬКО целям `tofu-*` и только для
|
||
привилегированных полей LXC. Ansible им не пользуется. Не логировать и не
|
||
передавать в playbook vars.
|
||
- В Git допустимы только sanitized `.env.example` и encrypted Vault content.
|
||
- Secret-bearing tasks должны использовать `no_log: true`, а files - минимальные
|
||
permissions.
|
||
|
||
## Рабочий процесс
|
||
|
||
1. Прочитай минимальный релевантный context и Obsidian notes.
|
||
2. Проверь active inventory, vars, playbook/role и связанные consumers.
|
||
3. Внеси smallest correct declarative change; не используй ad-hoc server edits.
|
||
4. Запусти минимальные local checks, затем только необходимые bounded live checks.
|
||
5. Проверь diff на broad targeting, secrets, destructive behavior и docs drift.
|
||
6. Обнови repository/Obsidian documentation для изменившихся решений и процедур.
|
||
7. В отчете перечисли changed files, проверки, неисполненные live checks и unknowns.
|
||
|
||
Для read-only reconnaissance, Ansible safety review, syntax validation, network/log
|
||
diagnostics, backup audit и Obsidian context используй специализированные агенты из
|
||
`.opencode/agents/`. Большие logs и command outputs передавай соответствующему
|
||
read-only summarizer и всегда ограничивай `--since`, `-n` или `--tail`.
|