#!/usr/bin/env bash
# backup/stages/sqlite-backup.sh
# Uses the `.backup` command so it is safe against concurrent writers.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=/dev/null
. "${HERE}/../../scripts/lib/log.sh"
DEST_ROOT="${DEST_ROOT:-/srv/homelab/backup/snapshots/sqlite}"
LATEST="${LATEST:-/srv/homelab/backup/latest/sqlite}"
TS="$(date +%Y%m%dT%H%M%S)"
DEST="${DEST_ROOT}/${TS}"
# Pairs of "label:path"
DBS=(
"grafana:/srv/homelab/stacks/monitoring/grafana/grafana.db"
"authelia:/srv/homelab/stacks/auth/authelia/db.sqlite3"
"lldap:/srv/homelab/stacks/auth/lldap/users.db"
"bazarr:/srv/homelab/stacks/media/bazarr/db/bazarr.db"
"jellyfin:/srv/homelab/stacks/media/jellyfin/data/jellyfin.db"
)
backup_one() {
local label="$1" src="$2"
if [[ ! -f "${src}" ]]; then
log_info "skip ${label} (missing ${src})"
return 0
fi
local tmp="${DEST}/${label}.sqlite"
if sqlite3 "${src}" ".backup '${tmp}'"; then
zstd -q -T0 -3 --rm "${tmp}"
log_info "backed up ${label}"
else
log_err "backup failed for ${label}"
return 1
fi
}
main() {
if ! command -v sqlite3 >/dev/null 2>&1; then
log_err "sqlite3 not installed"
exit 2
fi
install -d "${DEST}"
local failed=0
for pair in "${DBS[@]}"; do
backup_one "${pair%%:*}" "${pair#*:}" || failed=$((failed + 1))
done
if (( failed > 0 )); then
exit 1
fi
install -d "$(dirname "${LATEST}")"
rm -f "${LATEST}"
ln -s "${DEST}" "${LATEST}"
}
main "$@"