#!/bin/sh # System configuration backup script # Backs up /etc and dotfiles (lightweight backup) set -e # Config CONFIG_FILE="/etc/backup.conf" LOG_DIR="${HOME}/.local/var/log" LOG_FILE="${LOG_DIR}/backup.log" LOCK_FILE="/tmp/backup-configs.lock" # Ensure log directory exists mkdir -p "$LOG_DIR" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$LOG_FILE" echo "$*" } error() { printf "${RED}✖${NC} %s\n" "$1" log "ERROR: $1" } info() { printf "${BLUE}ℹ${NC} %s\n" "$1" log "INFO: $1" } success() { printf "${GREEN}✓${NC} %s\n" "$1" log "SUCCESS: $1" } # Load config if [ ! -f "$CONFIG_FILE" ]; then error "Configuration file not found: $CONFIG_FILE" exit 1 fi # shellcheck source=/dev/null . "$CONFIG_FILE" # Create lock file if [ -f "$LOCK_FILE" ]; then error "Config backup already running" exit 1 fi trap 'rm -f "$LOCK_FILE"' EXIT touch "$LOCK_FILE" # Start backup log "==========================================" log "Starting CONFIGURATION BACKUP" log "==========================================" # Check NAS connectivity info "Checking NAS connectivity..." if ! ssh -p "$NAS_PORT" -o ConnectTimeout=5 -o BatchMode=yes \ "${NAS_USER}@${NAS_HOST}" "echo test" >/dev/null 2>&1; then error "SSH connection to NAS failed" exit 1 fi success "NAS is reachable" # Create backup directory name with timestamp BACKUP_NAME="config-$(date +%Y%m%d-%H%M%S)" BACKUP_DEST="${NAS_USER}@${NAS_HOST}:${NAS_PATH}/${BACKUP_NAME}" info "Backup destination: ${BACKUP_DEST}" # Create temporary directory for staging TEMP_DIR=$(mktemp -d) trap 'rm -rf "$TEMP_DIR" 2>/dev/null; rm -f "$LOCK_FILE"' EXIT CONFIG_STAGE="$TEMP_DIR/configs" mkdir -p "$CONFIG_STAGE" # Copy /etc (excluding large/unnecessary files) info "Copying system configs from /etc..." rsync -a --delete \ --exclude='ssl/certs' \ --exclude='ca-certificates' \ /etc/ "$CONFIG_STAGE/etc/" 2>/dev/null || true # Copy important dotfiles from home info "Copying dotfiles..." mkdir -p "$CONFIG_STAGE/home" # Copy select dotfiles and configs for item in \ .zshrc .bashrc .gitconfig .gitmux.conf \ .config/nvim \ .config/hypr \ .config/waybar \ .config/tmux \ .config/bat \ .config/starship.toml \ .config/ghostty \ .config/alxndrhi \ .local/share/chezmoi; do if [ -e "/home/alexander/$item" ]; then mkdir -p "$(dirname "$CONFIG_STAGE/home/$item")" cp -r "/home/alexander/$item" "$CONFIG_STAGE/home/$item" 2>/dev/null || true fi done # Copy portage config info "Copying Portage configuration..." if [ -d /etc/portage ]; then mkdir -p "$CONFIG_STAGE/portage" cp -r /etc/portage/* "$CONFIG_STAGE/portage/" 2>/dev/null || true fi # Copy system scripts info "Copying custom scripts..." if [ -d /usr/local/bin ]; then mkdir -p "$CONFIG_STAGE/scripts" cp -r /usr/local/bin/* "$CONFIG_STAGE/scripts/" 2>/dev/null || true fi # Create a manifest file info "Creating backup manifest..." cat > "$CONFIG_STAGE/MANIFEST.txt" <> "$LOG_FILE" 2>&1; then success "Backup completed successfully!" # Update last backup timestamp LAST_BACKUP_FILE="${HOME}/.local/var/backup/last-backup" mkdir -p "$(dirname "$LAST_BACKUP_FILE")" date +%s > "$LAST_BACKUP_FILE" # Log backup size BACKUP_SIZE=$(ssh -p "$NAS_PORT" "${NAS_USER}@${NAS_HOST}" \ "du -sh '${NAS_PATH}/${BACKUP_NAME}' 2>/dev/null | cut -f1" || echo "unknown") info "Backup size: $BACKUP_SIZE" # Clean up old backups info "Cleaning up old backups (keeping last ${RETENTION_COUNT})..." ssh -p "$NAS_PORT" "${NAS_USER}@${NAS_HOST}" \ "cd '${NAS_PATH}' && ls -t | grep '^config-' | tail -n +$((RETENTION_COUNT + 1)) | xargs -r rm -rf" \ >> "$LOG_FILE" 2>&1 || true else error "Backup failed! Check $LOG_FILE for details" exit 1 fi log "==========================================" log "Backup completed at $(date)" log "=========================================="