From a5ee057c593937022d777538f8153a4c8bd6b16b Mon Sep 17 00:00:00 2001 From: goodvin Date: Tue, 13 Oct 2026 20:54:19 +0300 Subject: [PATCH] deploy: keep config backups out of dnsmasq conf dirs, cap at 10 Backups were written as .backup. next to the live file. Both dnsmasq instances load every file in their conf dir (the host excludes only .dpkg-*), so each backup was parsed as live config, resurrecting removed domains and piling up one stale copy per deploy. Write them to BACKUP_DIR (/var/backups/bbrkn) instead and keep the newest BACKUP_KEEP (10) per file. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01DR7zpSsdX28T4Kn6v4jPSS --- README.md | 2 ++ scripts/deploy-to-gateway.sh | 24 ++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c08766..a5cb7db 100644 --- a/README.md +++ b/README.md @@ -132,6 +132,8 @@ make warm # прогреть nft-сеты (запускать на шл | `TARGET_DIR` | `/opt/appdata/pihole/etc/dnsmasq.d` | Директория dnsmasq в Pi-hole (для `92-resolve`) | | `DOCKER_CONTAINER` | `pihole` | Имя Docker-контейнера Pi-hole | | `HOST_DNSMASQ_SVC` | `dnsmasq` | systemd-сервис host-инстанса dnsmasq | +| `BACKUP_DIR` | `/var/backups/bbrkn` | Куда класть бэкапы конфигов перед деплоем (НЕ в `dnsmasq.d` — оттуда грузится всё) | +| `BACKUP_KEEP` | `10` | Сколько последних бэкапов хранить на каждый файл | | `NFT_SETS` | `inet filter bbrkn_v4;inet filter bbrkn_v6` | Сеты для flush после деплоя (через `;`) | | `DNS_LISTEN_ADDR` | `127.0.0.1` | Адрес, на котором Pi-hole слушает DNS (:53) | | `DNS_CHECK_DOMAIN` | `google.com` | Домен базового DNS health check | diff --git a/scripts/deploy-to-gateway.sh b/scripts/deploy-to-gateway.sh index beadb0f..89763c7 100644 --- a/scripts/deploy-to-gateway.sh +++ b/scripts/deploy-to-gateway.sh @@ -14,6 +14,11 @@ RESOLVE_CONF="${RESOLVE_CONF:-/tmp/92-resolve-bbrkn.conf}" NFTSET_TARGET_DIR="${NFTSET_TARGET_DIR:-/etc/dnsmasq.d}" RESOLVE_TARGET_DIR="${RESOLVE_TARGET_DIR:-${TARGET_DIR:-/opt/appdata/pihole/etc/dnsmasq.d}}" +# Бэкапы — ВНЕ conf-dir: dnsmasq (и pihole) грузит из dnsmasq.d все файлы, +# кроме исключённых расширений, так что *.backup.* там стал бы живым конфигом. +BACKUP_DIR="${BACKUP_DIR:-/var/backups/bbrkn}" +BACKUP_KEEP="${BACKUP_KEEP:-10}" # сколько последних копий хранить на каждый файл + DOCKER_CONTAINER="${DOCKER_CONTAINER:-pihole}" # systemd-сервис host-инстанса dnsmasq (:5350) HOST_DNSMASQ_SVC="${HOST_DNSMASQ_SVC:-dnsmasq}" @@ -82,16 +87,31 @@ rollback() { # ============================== # Бэкап существующих файлов # ============================== +# Оставляет BACKUP_KEEP самых свежих копий .backup. +# (ts вида YYYYmmdd-HHMMSS сортируется лексикографически). +prune_backups() { # + local name="$1" old + find "$BACKUP_DIR" -maxdepth 1 -type f -name "${name}.backup.*" -printf '%f\n' \ + | sort -r | tail -n +"$((BACKUP_KEEP + 1))" \ + | while read -r old; do + rm -f -- "$BACKUP_DIR/$old" + echo " pruned old backup $old" + done +} + +mkdir -p "$BACKUP_DIR" ts=$(date +%Y%m%d-%H%M%S) if [ -f "$nftset_dest" ]; then - NFTSET_BACKUP="${nftset_dest}.backup.${ts}" + NFTSET_BACKUP="$BACKUP_DIR/${nftset_name}.backup.${ts}" cp "$nftset_dest" "$NFTSET_BACKUP" echo "Backed up $nftset_dest → $NFTSET_BACKUP" + prune_backups "$nftset_name" fi if [ -f "$resolve_dest" ]; then - RESOLVE_BACKUP="${resolve_dest}.backup.${ts}" + RESOLVE_BACKUP="$BACKUP_DIR/${resolve_name}.backup.${ts}" cp "$resolve_dest" "$RESOLVE_BACKUP" echo "Backed up $resolve_dest → $RESOLVE_BACKUP" + prune_backups "$resolve_name" fi # ==============================