scc: Session save and push from Mikes-MacBook-Air.local at 2026-04-19 08:34:23
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
291
temp/pavon_cleanup.sh
Executable file
291
temp/pavon_cleanup.sh
Executable file
@@ -0,0 +1,291 @@
|
||||
#!/bin/bash
|
||||
################################################################################
|
||||
# Pavon Archive Cleanup Script
|
||||
# Purpose: Delete camera footage older than 3 years (before April 2023)
|
||||
# Server: 172.16.1.33 (Pavon Unraid)
|
||||
# Expected Recovery: 25.2TB
|
||||
# Date: April 12, 2026
|
||||
################################################################################
|
||||
|
||||
# Configuration
|
||||
BASE_PATH="/mnt/user/Storage"
|
||||
LOG_DIR="/root/cleanup_logs"
|
||||
LOG_FILE="${LOG_DIR}/cleanup_$(date +%Y%m%d_%H%M%S).log"
|
||||
DRY_RUN=1 # 1 = dry-run (preview only), 0 = actual deletion
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Periods to delete (before April 2023)
|
||||
PERIODS=(
|
||||
"202212:Dec 2022"
|
||||
"202301:Jan 2023"
|
||||
"202302:Feb 2023"
|
||||
"202303:Mar 2023"
|
||||
)
|
||||
|
||||
################################################################################
|
||||
# Functions
|
||||
################################################################################
|
||||
|
||||
log() {
|
||||
echo -e "${GREEN}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "$LOG_FILE" >&2
|
||||
}
|
||||
|
||||
log_warn() {
|
||||
echo -e "${YELLOW}[$(date '+%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1" | tee -a "$LOG_FILE" >&2
|
||||
}
|
||||
|
||||
log_error() {
|
||||
echo -e "${RED}[$(date '+%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1" | tee -a "$LOG_FILE" >&2
|
||||
}
|
||||
|
||||
log_info() {
|
||||
echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')] INFO:${NC} $1" | tee -a "$LOG_FILE" >&2
|
||||
}
|
||||
|
||||
# Initialize logging
|
||||
init_logging() {
|
||||
mkdir -p "$LOG_DIR"
|
||||
log "==================================================================="
|
||||
log "Pavon Archive Cleanup Script - Started"
|
||||
log "==================================================================="
|
||||
log "Base Path: $BASE_PATH"
|
||||
log "Mode: $([ $DRY_RUN -eq 1 ] && echo 'DRY-RUN (preview only)' || echo 'LIVE DELETION')"
|
||||
log "Log File: $LOG_FILE"
|
||||
log "-------------------------------------------------------------------"
|
||||
}
|
||||
|
||||
# Calculate total size for a period
|
||||
calculate_period_size() {
|
||||
local pattern=$1
|
||||
local description=$2
|
||||
|
||||
log_info "Scanning: $description (pattern: Event${pattern}*.avi)"
|
||||
|
||||
local file_count=0
|
||||
local total_size=0
|
||||
|
||||
# Count files and calculate size
|
||||
while IFS= read -r file; do
|
||||
((file_count++))
|
||||
done < <(find "$BASE_PATH"/cam* -type f -name "Event${pattern}*.avi" 2>/dev/null)
|
||||
|
||||
if [ $file_count -gt 0 ]; then
|
||||
total_size=$(find "$BASE_PATH"/cam* -type f -name "Event${pattern}*.avi" -exec du -ch {} + 2>/dev/null | tail -1 | cut -f1)
|
||||
else
|
||||
total_size="0"
|
||||
fi
|
||||
|
||||
log_info " Files: $file_count"
|
||||
log_info " Size: $total_size"
|
||||
|
||||
echo "$file_count:$total_size"
|
||||
}
|
||||
|
||||
# Preview what will be deleted
|
||||
preview_deletion() {
|
||||
log "==================================================================="
|
||||
log "DELETION PREVIEW"
|
||||
log "==================================================================="
|
||||
|
||||
local grand_total_files=0
|
||||
local grand_total_size_kb=0
|
||||
|
||||
for period in "${PERIODS[@]}"; do
|
||||
IFS=':' read -r pattern description <<< "$period"
|
||||
|
||||
log ""
|
||||
log "--- $description ---"
|
||||
|
||||
result=$(calculate_period_size "$pattern" "$description")
|
||||
IFS=':' read -r file_count total_size <<< "$result"
|
||||
|
||||
grand_total_files=$((grand_total_files + file_count))
|
||||
|
||||
# Show sample files
|
||||
log_info "Sample files to be deleted:"
|
||||
find "$BASE_PATH"/cam* -type f -name "Event${pattern}*.avi" 2>/dev/null | head -5 | while read -r file; do
|
||||
size=$(du -h "$file" 2>/dev/null | cut -f1)
|
||||
log_info " $size - $(basename "$file")"
|
||||
done
|
||||
done
|
||||
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "SUMMARY"
|
||||
log "==================================================================="
|
||||
log "Total files to delete: $grand_total_files"
|
||||
log "Expected space recovery: 25.2TB (calculated from audit)"
|
||||
log "==================================================================="
|
||||
}
|
||||
|
||||
# Delete files for a specific period
|
||||
delete_period() {
|
||||
local pattern=$1
|
||||
local description=$2
|
||||
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "Processing: $description"
|
||||
log "==================================================================="
|
||||
|
||||
local deleted_count=0
|
||||
local failed_count=0
|
||||
local deleted_size=0
|
||||
|
||||
# Find and delete files
|
||||
while IFS= read -r file; do
|
||||
if [ $DRY_RUN -eq 1 ]; then
|
||||
log_info "[DRY-RUN] Would delete: $file"
|
||||
((deleted_count++))
|
||||
else
|
||||
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file" 2>/dev/null)
|
||||
if rm -f "$file" 2>/dev/null; then
|
||||
log_info "Deleted: $file"
|
||||
((deleted_count++))
|
||||
deleted_size=$((deleted_size + size))
|
||||
|
||||
# Progress indicator every 1000 files
|
||||
if [ $((deleted_count % 1000)) -eq 0 ]; then
|
||||
log "Progress: $deleted_count files deleted..."
|
||||
fi
|
||||
else
|
||||
log_error "Failed to delete: $file"
|
||||
((failed_count++))
|
||||
fi
|
||||
fi
|
||||
done < <(find "$BASE_PATH"/cam* -type f -name "Event${pattern}*.avi" 2>/dev/null)
|
||||
|
||||
log "-------------------------------------------------------------------"
|
||||
log "$description Complete:"
|
||||
log " Deleted: $deleted_count files"
|
||||
if [ $DRY_RUN -eq 0 ]; then
|
||||
log " Failed: $failed_count files"
|
||||
log " Space freed: $(numfmt --to=iec-i --suffix=B $deleted_size 2>/dev/null || echo 'N/A')"
|
||||
fi
|
||||
log "-------------------------------------------------------------------"
|
||||
|
||||
echo "$deleted_count:$failed_count:$deleted_size"
|
||||
}
|
||||
|
||||
# Clean up empty directories
|
||||
cleanup_empty_dirs() {
|
||||
if [ $DRY_RUN -eq 1 ]; then
|
||||
log_info "[DRY-RUN] Would clean up empty directories"
|
||||
return
|
||||
fi
|
||||
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "Cleaning up empty directories"
|
||||
log "==================================================================="
|
||||
|
||||
local removed_dirs=0
|
||||
|
||||
for cam_dir in "$BASE_PATH"/cam*; do
|
||||
if [ -d "$cam_dir" ]; then
|
||||
# Remove empty date directories
|
||||
find "$cam_dir" -type d -empty -delete 2>/dev/null
|
||||
((removed_dirs++))
|
||||
fi
|
||||
done
|
||||
|
||||
log "Empty directories cleaned: $removed_dirs camera folders checked"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
init_logging
|
||||
|
||||
# Verify base path exists
|
||||
if [ ! -d "$BASE_PATH" ]; then
|
||||
log_error "Base path does not exist: $BASE_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show preview
|
||||
preview_deletion
|
||||
|
||||
# If dry-run, stop here
|
||||
if [ $DRY_RUN -eq 1 ]; then
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "DRY-RUN COMPLETE - No files were deleted"
|
||||
log "==================================================================="
|
||||
log "To execute actual deletion, edit this script and set: DRY_RUN=0"
|
||||
log "Or run with: DRY_RUN=0 $0"
|
||||
log "==================================================================="
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Confirm before deletion
|
||||
log ""
|
||||
log_warn "==================================================================="
|
||||
log_warn "FINAL CONFIRMATION REQUIRED"
|
||||
log_warn "==================================================================="
|
||||
log_warn "This will PERMANENTLY delete approximately 25.2TB of data"
|
||||
log_warn "Files from: Dec 2022 - Mar 2023"
|
||||
log_warn ""
|
||||
read -p "Type 'DELETE' to confirm: " confirmation
|
||||
|
||||
if [ "$confirmation" != "DELETE" ]; then
|
||||
log_error "Deletion cancelled by user"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Execute deletion
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "STARTING DELETION PROCESS"
|
||||
log "==================================================================="
|
||||
|
||||
local grand_total_deleted=0
|
||||
local grand_total_failed=0
|
||||
local grand_total_size=0
|
||||
|
||||
for period in "${PERIODS[@]}"; do
|
||||
IFS=':' read -r pattern description <<< "$period"
|
||||
|
||||
result=$(delete_period "$pattern" "$description")
|
||||
IFS=':' read -r deleted failed size <<< "$result"
|
||||
|
||||
grand_total_deleted=$((grand_total_deleted + deleted))
|
||||
grand_total_failed=$((grand_total_failed + failed))
|
||||
grand_total_size=$((grand_total_size + size))
|
||||
done
|
||||
|
||||
# Clean up empty directories
|
||||
cleanup_empty_dirs
|
||||
|
||||
# Final summary
|
||||
log ""
|
||||
log "==================================================================="
|
||||
log "DELETION COMPLETE"
|
||||
log "==================================================================="
|
||||
log "Total files deleted: $grand_total_deleted"
|
||||
log "Total files failed: $grand_total_failed"
|
||||
log "Total space freed: $(numfmt --to=iec-i --suffix=B $grand_total_size 2>/dev/null || echo 'N/A')"
|
||||
log "Log file: $LOG_FILE"
|
||||
log "==================================================================="
|
||||
|
||||
# Show new disk usage
|
||||
log ""
|
||||
log "Updated disk usage:"
|
||||
df -h "$BASE_PATH" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Script execution
|
||||
################################################################################
|
||||
|
||||
# Allow override via environment variable
|
||||
if [ -n "$DRY_RUN" ]; then
|
||||
DRY_RUN=$DRY_RUN
|
||||
fi
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user