Files

49 lines
3.3 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# Выгрузка бэкапа fr1 для rpi. Forced command в ~rus/.ssh/authorized_keys:
# restrict,command="/home/rus/bin/backup-export" <ключ server-backup@rpi>
# Клиент передаёт профиль: daily | weekly. В stdout — tar | zstd | age (шифрует ОТКРЫТЫМ
# ключом, закрытый только у владельца вне малины — rpi хранит то, что сама прочитать не может).
# В stderr последней строкой — "SHA256 <hex>" шифротекста: rpi сверяет, что дошло целиком.
#
# Читает root-файлы через docker (rus в группе docker = root-эквивалент), а не через sudo:
# sudo на fr1 по паролю. Монтирование / только read-only.
set -euo pipefail
PUB=age1qfsgzyglv0vmq4kskg888hzgq032mry5kxz9kptkvzsrz0fz0v7q6kxwk2
AGE=/home/rus/bin/age
IMG=debian:stable-slim # GNU tar: --exclude/--warning, в alpine — busybox
profile="${SSH_ORIGINAL_COMMAND:-daily}"
tmp=$(mktemp -d /tmp/backup-export.XXXXXX)
cleanup() { rm -rf "$tmp"; docker exec gitea rm -f /tmp/gitea-snap.db >/dev/null 2>&1 || true; }
trap cleanup EXIT
case "$profile" in
daily)
# Gitea на SQLite: копировать живой gitea.db нельзя (рваная копия) — .backup даёт согласованный снимок
docker exec -u 1000 gitea sqlite3 /data/gitea.db ".backup '/tmp/gitea-snap.db'"
docker cp gitea:/tmp/gitea-snap.db "$tmp/gitea.db" >/dev/null
paths=(host/etc host/srv/gitea host/usr/local host/home/rus host/var/spool/cron host/root snap)
excl=(--exclude=host/srv/gitea/data/gitea.db --exclude='host/srv/gitea/data/gitea.db-*'
--exclude=host/home/rus/backups --exclude=host/home/rus/.openclaw
--exclude=host/home/rus/openclaw --exclude=host/home/rus/openclaw-work
--exclude=host/home/rus/.cache --exclude=host/home/rus/.claude --exclude='*.bak-*' --exclude='*.tar.gz')
;;
weekly)
paths=(host/var/lib/docker/volumes/claude-channels_claude-home
host/var/lib/docker/volumes/monitoring_grafana_data
host/var/lib/docker/volumes/monitoring_alertmanager_data
host/var/lib/docker/volumes/monitoring_pushgateway_data
host/home/tgclaude)
excl=(--exclude=host/home/tgclaude/backups --exclude=host/home/tgclaude/openclaw-deploy
--exclude=host/home/tgclaude/.local --exclude=host/home/tgclaude/.cache --exclude=host/home/tgclaude/chrome-libs)
;;
*) echo "профиль: daily|weekly" >&2; exit 2 ;;
esac
# tar exit 1 = «файл изменился при чтении» (живые логи/репо) — не ошибка для бэкапа
docker run --rm --network none -v /:/host:ro -v "$tmp":/snap:ro "$IMG" \
sh -c 'tar --numeric-owner --ignore-failed-read --warning=no-file-changed -C / -cf - "$@"; rc=$?; [ $rc -le 1 ] || exit $rc' tar "${excl[@]}" "${paths[@]}" \
| zstd -3 -T0 -q | "$AGE" -r "$PUB" | tee >(sha256sum > "$tmp/sum")
# процесс-подстановка живёт отдельно от конвейера — ждём, пока sha256sum допишет итог
for _ in $(seq 300); do [ -s "$tmp/sum" ] && break; sleep 0.1; done
echo "SHA256 $(cut -d' ' -f1 "$tmp/sum")" >&2