204 lines
6.0 KiB
Bash
Executable File
204 lines
6.0 KiB
Bash
Executable File
#!/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
|