Initial commit of MyWorkspace - contains multiple projects and global workspace configuration

This commit is contained in:
DavidSaylor
2026-05-06 22:59:37 -05:00
commit 019e35b488
2520 changed files with 13634 additions and 0 deletions

319
BackupScript/backup.sh Normal file
View File

@@ -0,0 +1,319 @@
#!/bin/bash
# Prevent set -e from causing issues in testing
set -uo pipefail
SCRIPT_NAME=$(basename "$0")
# Log to stderr with timestamp
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $SCRIPT_NAME: $*" >&2
}
# Get current timestamp in seconds since epoch
get_timestamp() {
date +%s
}
# Set file modification time to a specific date
set_file_mtime() {
local file="$1"
local new_date="$2"
touch -d "$new_date" "$file"
}
# --- Testing Functions ---
# Function to create test backup files with manipulated timestamps
create_test_backups() {
local dest_dir="${1:-/mnt/Backup/Ubuntu/Backups}"
local use_test_timestamp="${2:-now}"
log "Creating test backup files in $dest_dir (using timestamp: $use_test_timestamp)"
# Create the directory
mkdir -p "$dest_dir"
local now_ts=$(get_timestamp)
local now_date=$(date '+%Y-%m-%d')
# Convert relative days to timestamp
days_ago() {
local d="$1"
date -d "${d} days ago" +%s 2>/dev/null || echo ""
}
case "$use_test_timestamp" in
"today")
set_file_mtime "$dest_dir/test-today.tgz" "$now_date"
log "Created test file: test-today.tgz (today)"
;;
"yesterday")
set_file_mtime "$dest_dir/test-yesterday.tgz" "$(days_ago 1)"
log "Created test file: test-yesterday.tgz (1 day ago)"
;;
"3days")
set_file_mtime "$dest_dir/test-3days.tgz" "$(days_ago 3)"
log "Created test file: test-3days.tgz (3 days ago)"
;;
"6days")
set_file_mtime "$dest_dir/test-6days.tgz" "$(days_ago 6)"
log "Created test file: test-6days.tgz (6 days ago)"
;;
"7days")
set_file_mtime "$dest_dir/test-7days.tgz" "$(days_ago 7)"
log "Created test file: test-7days.tgz (7 days ago)"
;;
"14days")
set_file_mtime "$dest_dir/test-14days.tgz" "$(days_ago 14)"
log "Created test file: test-14days.tgz (14 days ago)"
;;
"29days")
set_file_mtime "$dest_dir/test-29days.tgz" "$(days_ago 29)"
log "Created test file: test-29days.tgz (29 days ago)"
;;
"60days")
set_file_mtime "$dest_dir/test-60days.tgz" "$(days_ago 60)"
log "Created test file: test-60days.tgz (60 days ago)"
;;
"90days")
set_file_mtime "$dest_dir/test-90days.tgz" "$(days_ago 90)"
log "Created test file: test-90days.tgz (90 days ago)"
;;
"monday")
# Get yesterday's date, check if Monday, otherwise find next Monday
local check_date=$(date -d "yesterday" '+%A')
if [ "$check_date" = "Monday" ]; then
set_file_mtime "$dest_dir/test-monday.tgz" "$(days_ago 1)"
log "Created test file: test-monday.tgz (yesterday/Monday)"
else
# Find next Monday (2 days from now if today is Saturday, etc.)
local days_to_monday=$(( (1 + (6 - $(date +%w))) % 7 ))
set_file_mtime "$dest_dir/test-monday.tgz" "$(days_ago $days_to_monday)"
log "Created test file: test-monday.tgz (previous Monday)"
fi
;;
"sunday")
# Find the most recent Sunday
local days_to_sunday=$(( (date +%w) % 7 ))
set_file_mtime "$dest_dir/test-sunday.tgz" "$(days_ago $days_to_sunday)"
log "Created test file: test-sunday.tgz (most recent Sunday)"
;;
"1st")
# Get the 1st day of current month
current_month=$(date +%m)
set_file_mtime "$dest_dir/test-1st.tgz" "$(date -d "${current_month}-01" '+%s')"
log "Created test file: test-1st.tgz (1st of this month)"
;;
*)
log "Unknown timestamp option: $use_test_timestamp"
;;
esac
}
# Create test files for multiple scenarios
create_all_test_backups() {
local dest_dir="${1:-/mnt/Backup/Ubuntu/Backups}"
log "Creating comprehensive test backup files in $dest_dir"
create_test_backups "$dest_dir" "today"
create_test_backups "$dest_dir" "yesterday"
create_test_backups "$dest_dir" "3days"
create_test_backups "$dest_dir" "6days"
create_test_backups "$dest_dir" "7days"
create_test_backups "$dest_dir" "14days"
create_test_backups "$dest_dir" "29days"
create_test_backups "$dest_dir" "60days"
create_test_backups "$dest_dir" "90days"
create_test_backups "$dest_dir" "monday"
create_test_backups "$dest_dir" "sunday"
create_test_backups "$dest_dir" "1st"
log "Test backup files created. Run ./backup.sh to test retention logic."
}
# --- Configuration ---
# Backup 1: /mnt/Content → /mnt/Backup (rsync sync)
CONTENT_SRC="/mnt/Content"
CONTENT_DEST="/mnt/Backup"
CONTENT_EXCLUDES="/etc/backup-excludes/content.exclude"
# Backup 2: / (root filesystem) → /mnt/Backup/Ubuntu/Backups (compressed tar)
UBUNTU_DEST="/mnt/Backup/Ubuntu/Backups"
UBUNTU_EXCLUDES="/etc/backup-excludes/ubuntu.exclude"
# === Helper Functions ===
# Run rsync with low CPU and I/O priority
run_rsync() {
local label="$1"
shift
log "Starting low-priority rsync ($label)"
nice -n 19 ionice -c 3 rsync -avHAX "$@"
}
# 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 "$@"
}
# === Task 1: Sync /mnt/Content → /mnt/Backup ===
if [ -d "$CONTENT_SRC" ]; then
log "Starting rsync of $CONTENT_SRC$CONTENT_DEST (with excludes)"
# Ensure destination directory exists
run_low_priority "Create destination" \
mkdir -p "$CONTENT_DEST"
# Use --delete to sync deletions - frees space at destination
run_rsync "Content -> Backup (media)" \
--delete-before \
--exclude-from="$CONTENT_EXCLUDES" \
"$CONTENT_SRC"/ "$CONTENT_DEST"/
log "Finished $CONTENT_SRC$CONTENT_DEST backup."
else
log "WARNING: $CONTENT_SRC not found or not a directory; skipping."
fi
# === Task 2: Full filesystem backup with compression ===
log "Starting tar backup of / → $UBUNTU_DEST (excluding system paths)"
# Ensure destination directory exists
run_low_priority "Create destination" \
mkdir -p "$UBUNTU_DEST"
# Generate timestamp for backup filename
timestamp=$(date +%Y-%m-%d)
# Create backup filename with timestamp
tar_output="$UBUNTU_DEST/backup-full-$timestamp.tgz"
log "Starting compressed backup of /..."
# Run tar with low priority (compression is I/O intensive)
run_low_priority "Full system backup" \
tar -czf "$tar_output" \
--exclude-from="$UBUNTU_EXCLUDES" \
/
log "Finished / → $UBUNTU_DEST backup."
# === Retention Management ===
log "Managing backup retention in $UBUNTU_DEST..."
# Create the directory if it doesn't exist (already done above, but for safety)
[ ! -d "$UBUNTU_DEST" ] && sudo mkdir -p "$UBUNTU_DEST"
# Count current totals
daily_count=0
weekly_count=0
monthly_count=0
if [ -n "$(ls -A "$UBUNTU_DEST"/*.tgz 2>/dev/null)" ]; then
# First pass: count existing files by type
for file in "$UBUNTU_DEST"/*.tgz; do
[ -f "$file" ] || continue
mtime=$(stat -c %Y "$file")
age=$(( ($(date +%s) - $mtime) / (3600 * 24) ))
backup_date=$(date -d "@$mtime" '+%Y-%m-%d')
day=$(date -d "$backup_date" +%d)
weekday=$(date -d "$backup_date" +%w) # 0=Sunday
if [ $age -lt 7 ]; then
((daily_count++))
fi
if [ $weekday -eq 0 ]; then
((weekly_count++))
fi
if [ $day -eq 01 ]; then
((monthly_count++))
fi
done
log "Current counts - Daily: $daily_count, Weekly: $weekly_count, Monthly: $monthly_count"
fi
# Process each backup file
if [ -n "$(ls -A "$UBUNTU_DEST"/*.tgz 2>/dev/null)" ]; then
for backup_file in $(ls -1 "$UBUNTU_DEST"/*.tgz | sort --key=1.2 --reverse); do
filename=$(basename "$backup_file")
mtime=$(stat -c %Y "$backup_file")
age=$(( ($(date +%s) - $mtime) / (3600 * 24) ))
# Calculate date of the backup
backup_date=$(date -d "@$mtime" '+%Y-%m-%d')
day=$(date -d "$backup_date" +%d)
month=$(date -d "$backup_date" +%m)
weekday=$(date -d "$backup_date" +%w) # 0=Sunday
# Calculate months since backup
backup_year=$(date -d "$backup_date" +%Y)
backup_month_int=$((10#$month))
current_month_int=$((10#$month))
current_year_int=$((10#$backup_year))
if [ $backup_month_int -lt $current_month_int ]; then
months_since=$(( (current_month_int - backup_month_int) + 12 ))
else
months_since=$(( current_month_int - backup_month_int ))
fi
if [ $backup_year_int -lt $current_year_int ]; then
months_since=$(( months_since + 12 ))
fi
# Determine backup type
is_daily=0
is_weekly=0
is_monthly=0
if [ $age -lt 7 ]; then
is_daily=1
fi
if [ $weekday -eq 0 ]; then
is_weekly=1
fi
if [ $day -eq 01 ]; then
is_monthly=1
fi
# Keep daily backups (less than 7 days old)
if [ $is_daily -eq 1 ]; then
log "Backup $filename: Keeping (daily backup, age: $age days)"
((daily_count++))
continue
fi
# Keep Sunday backups for the last month (31 days)
if [ $is_weekly -eq 1 ] && [ $age -lt 31 ]; then
log "Backup $filename: Keeping (weekly Sunday backup, age: $age days)"
((weekly_count++))
continue
fi
# Keep 1st-of-month backups for the last 3 months
if [ $is_monthly -eq 1 ] && [ $months_since -lt 3 ]; then
log "Backup $filename: Keeping (monthly 1st-of-month backup, age: $age days)"
((monthly_count++))
continue
fi
# Delete backup that doesn't meet retention criteria
log "Deleting backup: $filename (age: $age days, days_since: $months_since, type: none)"
sudo rm "$backup_file"
done
else
log "No backup files found in $UBUNTU_DEST"
fi
log "All backups completed."