mirror of
https://github.com/NickoScope/nickol-knx-mcp.git
synced 2026-09-29 19:31:12 +02:00
The nightly HA sync runs via shell_command in the Core container, not the SSH add-on where install ran. Core has an empty known_hosts, so git push failed "Host key verification failed" — the commit was made locally but never reached GitHub. install.sh now seeds a repo-local known_hosts (ssh-keyscan) and pins git config core.sshCommand so every context (add-on, Core, cron) uses the same working ssh. Also drops a stray `.git-sync` arg from the pre-commit chmod line. Records LESSON-06 + a symptom-table row in SKILL.md and SKILL.ru.md; CHANGELOG Fixed entry. Field-validated on a live Home Assistant.
7.0 KiB
7.0 KiB
HA Git Backup — двухконтурная система (русская версия; каноническая — SKILL.md)
Философия: git даёт историю, бэкап даёт восстановление. Это разные задачи — их решают разные контуры. Проекты типа GithubConfigSync смешивают их и реализуют git поверх Contents API — мы используем настоящий git.
Архитектура
КОНТУР 1: ИСТОРИЯ КОНФИГА (что изменилось и когда)
/config (git repo) ──deploy key──▶ GitHub private repo (ha-config)
├── триггеры: daily 03:30 / pre-update / кнопка / рестарт HA
├── защита секретов: .gitignore → pre-commit scan → age-зеркало
└── коммит: "[trigger] N files | HA 2026.7.1" + список файлов
КОНТУР 2: ВОССТАНОВЛЕНИЕ (полное состояние, включая .storage)
HA native backup (.tar) ──age──▶ GitHub Releases (ha-config)
├── расписание: еженедельно + перед обновлениями
├── ротация: 8 релизов
└── restore drill: 1-е число месяца (обязательный)
Правило 3-2-1: конфиг живёт (1) на хосте HA, (2) в git-репо GitHub, (3) полный тарбол в Releases + локальный NAS при наличии.
ЖЕЛЕЗНЫЕ ПРАВИЛА
- Deploy key, не PAT. Fine-grained доступ на ЗАПИСЬ в ОДИН репозиторий. Classic-токен со
scope
repo= доступ ко всем приватным репо → запрещён. - Секрет в diff = коммит блокируется. Pre-commit hook вызывает
secret_scan.sh. Обход через--no-verify— только осознанно и с записью причины в лог. .storage/НЕ идёт в git (auth, токены), кроме whitelistlovelace*— дашборды. Полное.storageживёт только в шифрованном тарболе Контура 2.- Бэкап без restore drill — не бэкап. Раз в месяц: скачать релиз →
age -d→tar -t→ проверить наличие.storage/core.config_entries. - Не переписывать скрипты с нуля. Логика (lock, retry, notify, ротация) уже в
scripts/— читать и использовать их.
Быстрый старт (новая установка)
- Создать приватный репо
ha-configна GitHub (пустой). - Прочитать
references/setup.md— там пошагово: deploy key, установка через SSH add-on. - Запустить
scripts/install.shвнутри HA — он делает git init, .gitignore, hook, remote, первый dry-run. - Добавить
assets/configuration_snippet.yamlв configuration.yaml иassets/automations.yamlв автоматизации. Нужен ПОЛНЫЙ перезапуск HA (quick-reload не грузитshell_command/command_line). - Контур 2:
scripts/backup_offsite.shтребует fine-grained PAT + age-ключ. См.references/setup.md§4. - Провести первый restore drill СРАЗУ — до того, как система понадобится.
Карта симптомов → действия
| Симптом | Действие |
|---|---|
| «Вчера работало, сегодня нет» | git log --oneline -10, git diff HEAD~1 в /config |
| Сломал YAML, HA не стартует | git checkout -- <file> или git reset --hard <good_sha>, рестарт |
| Утёк секрет в репо | references/incident-secret-leak.md — ротация секрета ПЕРВОЙ |
| Push молчит/падает | /config/.git-sync/log; типовое: deploy key read-only, протух known_hosts |
Ночной коммит есть локально, но не в GitHub (Host key verification failed в логе) |
shell_command идёт из Core-контейнера — закрепить git config core.sshCommand с repo-local known_hosts (см. УРОК-06); install.sh делает автоматически |
| Переезд на новое железо | scripts/restore.sh — тарбол Контура 2, НЕ git-репо (в git нет .storage) |
| Sync-сенсор = error | Смотреть лог; автоматизация шлёт persistent_notification |
| Репо распух | Бинарники (db, tar) в .gitignore; история чистится git gc |
УРОКИ (зафиксированы, не повторять)
- УРОК-01: GithubConfigSync-подход (файлы по одному через Contents API) = коммит на файл, rate limits, снапшоты-дубли. Настоящий git решает всё это бесплатно.
- УРОК-02: .gitignore — НЕ защита. Файл, добавленный до правила, продолжает трекаться. Отсюда обязательный pre-commit scan.
- УРОК-03: git-репо конфига ≠ бэкап: без .storage восстановление даёт голый HA без entity registry, авторизаций и дашбордов из UI.
- УРОК-04: restore drill в спокойное время стоит 10 минут. Первое восстановление во время аварии без drill стоит вечер и нервы.
- УРОК-05: BusyBox-grep принимает паттерн, начинающийся с
-, за опцию — паттерны сканера передавать только какgrep -E -e "$pattern". Сканер молча пропускал проверку приватных ключей, пока это не поймал тест с подсадной уткой. Проверяй сканер подсадными секретами. - УРОК-06: HA
shell_command(ночной синк) исполняется в контейнере Core, а не в SSH add-on, где шёл install. У Core свой пустой known_hosts →git pushпадаетHost key verification failed, хотя deploy key исправен — коммит делается локально, но не доходит до GitHub. Лечится закреплениемgit config core.sshCommand(ключ + repo-local known_hosts +accept-new) в.git/config— применяется из ЛЮБОГО контейнера. install.sh делает это автоматически. Проверять SSH только из add-on недостаточно — это не задевает контейнер, в котором реально идёт синк.