#!/usr/bin/env bash # backup-prune.sh — enforce retention "keep 30 daily + 12 monthly". # # Walks $BACKUP_DIR for librenotes-YYYYMMDD-HHMMSS.tar.gz and # deletes archives outside the retention policy. # - keep the most recent N daily archives (default 30) # - additionally keep the most recent archive of each of the # last M distinct months (default 12) # Anything else is removed. set -euo pipefail BACKUP_DIR="${BACKUP_DIR:-/var/backups/librenotes}" DAILY_KEEP="${DAILY_KEEP:-30}" MONTHLY_KEEP="${MONTHLY_KEEP:-12}" if [ ! -d "$BACKUP_DIR" ]; then echo "backup dir $BACKUP_DIR does not exist; nothing to prune" exit 0 fi cd "$BACKUP_DIR" # Sort archives by name (date is in the filename, lexicographic # order == chronological order). mapfile -t archives < <(ls -1 librenotes-*.tar.gz 2>/dev/null | sort) declare -A keep # Keep the newest DAILY_KEEP outright. for a in "${archives[@]: -$DAILY_KEEP}"; do keep["$a"]=1 done # Walk archives newest-first, recording one per month until we # have MONTHLY_KEEP distinct months. declare -A month_seen months_kept=0 for ((i=${#archives[@]}-1; i>=0; i--)); do a="${archives[$i]}" # filename: librenotes-YYYYMMDD-HHMMSS.tar.gz -> YYYYMM ym="${a:11:6}" if [ -z "${month_seen[$ym]:-}" ] && [ "$months_kept" -lt "$MONTHLY_KEEP" ]; then keep["$a"]=1 month_seen[$ym]=1 months_kept=$((months_kept + 1)) fi done removed=0 for a in "${archives[@]}"; do if [ -z "${keep[$a]:-}" ]; then rm -f "$a" removed=$((removed + 1)) fi done echo "kept ${#keep[@]} archives, removed $removed"