79 lines
2.8 KiB
Bash
79 lines
2.8 KiB
Bash
#!/usr/bin/env bash
|
|
# 🔄 Rotating Backup — keep N copies, replace oldest
|
|
#
|
|
# Usage:
|
|
# ./rotate-backup.sh [--keep N] [--dir DIR] <path/to/database.db>
|
|
#
|
|
# Examples:
|
|
# ./rotate-backup.sh /home/oplabs/projects/canteen-asset-tracker/assets.db
|
|
# ./rotate-backup.sh --keep 5 --dir /backups/dbs /var/lib/app/data.db
|
|
#
|
|
# Default: keep 3 backups in /home/oplabs/backups/canteen-db/
|
|
set -euo pipefail
|
|
|
|
KEEP=3
|
|
BACKUP_DIR="/home/oplabs/backups/canteen-db"
|
|
PREFIX="assets.db"
|
|
|
|
# ── Parse args ────────────────────────────────────────────────────────────────
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--keep) shift; KEEP="$1"; shift ;;
|
|
--dir) shift; BACKUP_DIR="$1"; shift ;;
|
|
--prefix) shift; PREFIX="$1"; shift ;;
|
|
-h|--help)
|
|
echo "Usage: $(basename "$0") [--keep N] [--dir DIR] [--prefix NAME] <database-path>"
|
|
echo ""
|
|
echo "Backs up a SQLite database with rotation (keep N, remove oldest)."
|
|
echo ""
|
|
echo " --keep N Number of backups to retain (default: 3)"
|
|
echo " --dir DIR Target backup directory (default: /home/oplabs/backups/canteen-db)"
|
|
echo " --prefix NAME Backup file name prefix (default: assets.db)"
|
|
exit 0
|
|
;;
|
|
-*)
|
|
echo "Unknown option: $1" >&2
|
|
exit 1
|
|
;;
|
|
*)
|
|
DB_PATH="$1"
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "${DB_PATH:-}" ]]; then
|
|
echo "❌ Usage: $(basename "$0") [--keep N] <database-path>" >&2
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -f "$DB_PATH" ]]; then
|
|
echo "❌ Database not found: $DB_PATH" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# ── Create backup ─────────────────────────────────────────────────────────────
|
|
mkdir -p "$BACKUP_DIR"
|
|
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
|
|
BACKUP_FILE="${BACKUP_DIR}/${PREFIX}-${TIMESTAMP}"
|
|
|
|
# Use sqlite3 .backup for safe online backup (consistent snapshot even if app is running)
|
|
if command -v sqlite3 &>/dev/null; then
|
|
sqlite3 "$DB_PATH" ".backup '$BACKUP_FILE'"
|
|
echo "✅ $(basename "$DB_PATH") → $BACKUP_FILE (sqlite3 snapshot)"
|
|
else
|
|
cp "$DB_PATH" "$BACKUP_FILE"
|
|
echo "✅ $(basename "$DB_PATH") → $BACKUP_FILE (file copy)"
|
|
fi
|
|
|
|
# ── Rotate: keep only N most recent ───────────────────────────────────────────
|
|
KEEP=$((KEEP + 0)) # ensure numeric
|
|
REMOVE_COUNT=$((KEEP))
|
|
REMOVE_FROM=$((REMOVE_COUNT + 1))
|
|
|
|
OLD_COUNT=$(ls -t "${BACKUP_DIR}/${PREFIX}-"* 2>/dev/null | wc -l)
|
|
ls -t "${BACKUP_DIR}/${PREFIX}-"* 2>/dev/null | tail -n +${REMOVE_FROM} | xargs rm -f 2>/dev/null || true
|
|
REMOVED=$((OLD_COUNT > KEEP ? OLD_COUNT - KEEP : 0))
|
|
|
|
echo " 📦 ${KEEP} kept · ${REMOVED} removed · ${BACKUP_DIR}"
|