#!/usr/bin/env bash # backup-rocknix.sh - Backup script for ROCKNIX configurations # # Usage: # ./backup-rocknix.sh [OPTIONS] # # Options: # --host HOST Console host (default: rgeubexx.local) # --user USER SSH user (default: root) # --output DIR Output directory for backups # --type TYPE Backup type: specific or generic (default: specific) # --help Show help set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/lib-common.sh" # Default values BACKUP_TYPE="specific" # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in --host) ROCKNIX_HOST="$2" shift 2 ;; --user) ROCKNIX_USER="$2" shift 2 ;; --password) ROCKNIX_PASSWORD="$2" shift 2 ;; --output) BACKUP_DIR="$2" shift 2 ;; --type) BACKUP_TYPE="$2" shift 2 ;; --help) echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" echo " --host HOST Console host (default: $ROCKNIX_HOST)" echo " --user USER SSH user (default: $ROCKNIX_USER)" echo " --password PASS SSH password" echo " --output DIR Output directory" echo " --type TYPE Backup type: specific, generic (default: specific)" echo " --help Show this help" exit 0 ;; *) log ERROR "Unknown option: $1" exit 1 ;; esac done # Verify valid type if [[ "$BACKUP_TYPE" != "specific" && "$BACKUP_TYPE" != "generic" ]]; then log ERROR "Invalid backup type: $BACKUP_TYPE (use: specific, generic)" exit 1 fi # Check dependencies check_deps || exit 1 # Ask for password if not configured ask_password || exit 1 # Verify SSH connection ssh_check "$ROCKNIX_HOST" "$ROCKNIX_USER" || exit 1 # Detect device DEVICE=$(detect_device "$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null || echo "unknown") DEVICE_SLUG=$(echo "$DEVICE" | tr ' ' '-' | tr '[:upper:]' '[:lower:]') # Create backups directory mkdir -p "$BACKUP_DIR" # Create temporary directory TMP_DIR=$(create_tmp_dir "rocknix-backup") trap 'cleanup_tmp "$TMP_DIR"' EXIT log INFO "Starting ${BACKUP_TYPE} backup..." log INFO "Device: ${DEVICE}" log INFO "Host: ${ROCKNIX_USER}@${ROCKNIX_HOST}" # Select file list based on type if [[ "$BACKUP_TYPE" == "specific" ]]; then FILES_TO_BACKUP=("${SPECIFIC_FILES[@]}") else # For generic, exclude device-specific files FILES_TO_BACKUP=() for file in "${SPECIFIC_FILES[@]}"; do skip=false for exclude in "${GENERIC_EXCLUDES[@]}"; do if [[ "$file" == "$exclude" ]]; then skip=true break fi done if [[ "$skip" == "false" ]]; then FILES_TO_BACKUP+=("$file") fi done fi # Download files log INFO "Downloading files..." DOWNLOADED=0 FAILED=0 for file in "${FILES_TO_BACKUP[@]}"; do local_path="${TMP_DIR}/${file}" remote_path="${file}" # Create local directory mkdir -p "$(dirname "$local_path")" # Download if [[ -d "${local_path}" ]] || [[ "$file" == */ ]]; then # It's a directory mkdir -p "$local_path" if download_dir "$remote_path" "$local_path" "$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then DOWNLOADED=$((DOWNLOADED + 1)) log DEBUG "Downloaded: ${file}" else FAILED=$((FAILED + 1)) log WARN "Could not download: ${file}" fi else # It's a file if download_file "$remote_path" "$local_path" "$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then DOWNLOADED=$((DOWNLOADED + 1)) log DEBUG "Downloaded: ${file}" else FAILED=$((FAILED + 1)) log WARN "Could not download: ${file}" fi fi done log INFO "Downloaded: ${DOWNLOADED} files" # For generic backup, filter device/user-specific settings if [[ "$BACKUP_TYPE" == "generic" ]]; then log INFO "Filtering device/user-specific settings..." # Filter retroarch-core-options.cfg if it exists if [[ -f "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" ]]; then filter_specific_settings \ "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" \ "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg.filtered" mv "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg.filtered" \ "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" fi # Filter overrides (.cfg files) find "${TMP_DIR}/.config/retroarch/config/" -name "*.cfg" -type f 2>/dev/null | while read -r cfg_file; do filter_specific_settings "$cfg_file" "${cfg_file}.filtered" mv "${cfg_file}.filtered" "$cfg_file" done fi # Create backup filename TIMESTAMP=$(date '+%Y%m%d-%H%M%S') BACKUP_NAME="rocknix-config-${BACKUP_TYPE}-${DEVICE_SLUG}-${TIMESTAMP}.tar.gz" BACKUP_FILE="${BACKUP_DIR}/${BACKUP_NAME}" # Compress log INFO "Compressing backup..." tar -czf "$BACKUP_FILE" -C "$TMP_DIR" . # Verify if [[ -f "$BACKUP_FILE" ]]; then BACKUP_SIZE=$(du -h "$BACKUP_FILE" | cut -f1) BACKUP_FILES=$(tar -tzf "$BACKUP_FILE" | wc -l) echo "" echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} Backup completed successfully${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e " Type: ${CYAN}${BACKUP_TYPE}${NC}" echo -e " Device: ${CYAN}${DEVICE}${NC}" echo -e " File: ${CYAN}${BACKUP_NAME}${NC}" echo -e " Location: ${CYAN}${BACKUP_DIR}${NC}" echo -e " Size: ${CYAN}${BACKUP_SIZE}${NC}" echo -e " Files: ${CYAN}${BACKUP_FILES}${NC}" echo "" echo -e " ${YELLOW}To restore, run:${NC}" echo -e " ${CYAN}./restore-rocknix.sh --backup ${BACKUP_FILE}${NC}" echo "" else log ERROR "Could not create backup file" exit 1 fi