124 lines
4.1 KiB
Bash
124 lines
4.1 KiB
Bash
#!/bin/bash
|
||
set -euo pipefail
|
||
|
||
SCRIPT_NAME=$(basename "$0")
|
||
log() {
|
||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $SCRIPT_NAME: $*" >&2
|
||
}
|
||
|
||
cd / || exit 1
|
||
|
||
#UBUNTU_DEST="/mnt/Backup/Ubuntu"
|
||
UBUNTU_DEST="/mnt/Backup/Ubuntu/Backups"
|
||
CONTENT_SRC="/mnt/Content"
|
||
CONTENT_DEST="/mnt/Backup"
|
||
|
||
# helper wrapper: run rsync with low CPU and low I/O priority
|
||
run_rsync() {
|
||
local label="$1"
|
||
shift
|
||
log "Starting low‑priority rsync ($label)"
|
||
nice -n 19 ionice -c 3 rsync -avHAX --delete "$@"
|
||
}
|
||
|
||
# Helper function: Run a command with low CPU and I/O priority
|
||
run_low_priority() {
|
||
local label="$1"
|
||
shift
|
||
log "Starting low-priority $label..."
|
||
nice -n 19 ionice -c 3 "$@"
|
||
}
|
||
|
||
# Function to manage backup lifecycle - keep dailies for the past week, keep weeklies for the past month, keep montlies for 6 months.
|
||
manage_backups() {
|
||
#local dir="/mnt/Backup/Ubuntu/Backups" - use UBUNTU_DEST
|
||
log "Managing backups in $dir..."
|
||
|
||
# Create the directory if it doesn't exist
|
||
[ ! -d "$UBUNTU_DEST" ] && sudo mkdir -p "$UBUNTU_DEST"
|
||
|
||
# List all .tgz files and sort them by modification time (oldest first)
|
||
for backup_file in $(sudo ls -1 $UBUNTU_DEST/*.tgz | sort --key=1.2 --reverse); do
|
||
filename=$(basename "$backup_file")
|
||
timestamp=$(echo "$filename" | cut -d'-' -f3- | cut -d '.' -f1)
|
||
|
||
# Calculate age in days
|
||
mtime=$(stat -c %Y "$backup_file")
|
||
age=$(( ($(date +%s) - $mtime) / (3600 * 24) ))
|
||
|
||
# Extract day, month, and weekday from timestamp
|
||
day=$(date -d "@$timestamp" +%d)
|
||
month=$(date -d "@$timestamp" +%m)
|
||
weekday=$(date -d "@$timestamp" +%w)
|
||
|
||
# Check if backup is less than a week old (daily retention)
|
||
if [ $age -lt 7 ]; then
|
||
log "Backup $filename is less than a week old. Keeping."
|
||
continue
|
||
fi
|
||
|
||
# Check for weekly backups on Sundays within the last month
|
||
if [ $weekday == '0' ]; then
|
||
current_month=$(date +%m)
|
||
months_since=$(( (current_month - $month) % 12 ))
|
||
if [ $months_since -lt 1 ]; then
|
||
log "Backup $filename is a weekly backup on Sunday within the last month. Keeping."
|
||
continue
|
||
fi
|
||
fi
|
||
|
||
# Check for monthly backups on first day of the month within six months
|
||
if [ $day == '01' ]; then
|
||
current_month=$(date +%m)
|
||
months_since=$(( (current_month - $month) % 12 ))
|
||
if [ $months_since -lt 6 ]; then
|
||
log "Backup $filename is a monthly backup on the first day within six months. Keeping."
|
||
continue
|
||
fi
|
||
fi
|
||
|
||
# Delete backups older than retention criteria
|
||
log "Deleting backup: $filename"
|
||
sudo rm "$backup_file"
|
||
done
|
||
}
|
||
|
||
# --- 1. Backup / → /mnt/Backup/Ubuntu (fast, configs + Docker) ---
|
||
|
||
log "Starting tar backup of / → $UBUNTU_DEST (excluding /mnt and pseudo‑dirs)"
|
||
|
||
sudo mkdir -p "$UBUNTU_DEST"
|
||
|
||
# no longer using rsync to backup main filesystem as single file backup using compression works better with remote sync - does not interfere with syncthing state files and folders at the destination
|
||
#run_rsync "Ubuntu configs & Docker" \
|
||
# --exclude-from=/etc/backup-excludes/ubuntu.exclude \
|
||
# / "$UBUNTU_DEST"/
|
||
|
||
# Create a compressed tar backup with timestamp in the filename
|
||
timestamp=$(date +%Y%m%d-%H%M%S)
|
||
tar_output="$UBUNTU_DEST/backup-full-$timestamp.tgz"
|
||
|
||
log "Starting backup of /..."
|
||
run_low_priority "Ubuntu full backup" \
|
||
tar -czf "$tar_output" --exclude-from=/etc/backup-excludes/ubuntu.exclude /
|
||
|
||
|
||
log "Finished / → $UBUNTU_DEST backup."
|
||
|
||
# --- 2. Backup /mnt/Content → /mnt/Backup (large media‑heavy sync) ---
|
||
|
||
if [ -d "$CONTENT_SRC" ]; then
|
||
log "Starting rsync of $CONTENT_SRC → $CONTENT_DEST (with excludes)"
|
||
|
||
# using --delete-before to ensure space is freed at destination for new and updated files
|
||
run_rsync "Content -> Backup (media)" \
|
||
--delete-before
|
||
--exclude-from=/etc/backup-excludes/content.exclude \
|
||
"$CONTENT_SRC"/ "$CONTENT_DEST"/
|
||
|
||
log "Finished $CONTENT_SRC → $CONTENT_DEST backup."
|
||
else
|
||
log "WARNING: $CONTENT_SRC not found or not a directory; skipping."
|
||
fi
|
||
|
||
log "All backups completed." |