first commit
This commit is contained in:
393
restore-rocknix.sh
Executable file
393
restore-rocknix.sh
Executable file
@@ -0,0 +1,393 @@
|
||||
#!/usr/bin/env bash
|
||||
# restore-rocknix.sh - Restore script for ROCKNIX configurations
|
||||
#
|
||||
# Usage:
|
||||
# ./restore-rocknix.sh [OPTIONS]
|
||||
#
|
||||
# Options:
|
||||
# --host HOST Target console host
|
||||
# --user USER SSH user (default: root)
|
||||
# --backup FILE .tar.gz backup file to restore
|
||||
# --all Restore all components without prompting
|
||||
# --help Show help
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
source "$SCRIPT_DIR/lib-common.sh"
|
||||
|
||||
# Default values
|
||||
BACKUP_FILE=""
|
||||
RESTORE_ALL=false
|
||||
|
||||
# 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
|
||||
;;
|
||||
--backup)
|
||||
BACKUP_FILE="$2"
|
||||
shift 2
|
||||
;;
|
||||
--all)
|
||||
RESTORE_ALL=true
|
||||
shift
|
||||
;;
|
||||
--help)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --host HOST Target console host"
|
||||
echo " --user USER SSH user (default: $ROCKNIX_USER)"
|
||||
echo " --password PASS SSH password"
|
||||
echo " --backup FILE .tar.gz backup file to restore"
|
||||
echo " --all Restore all components"
|
||||
echo " --help Show this help"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
log ERROR "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Check dependencies
|
||||
check_deps || exit 1
|
||||
|
||||
# Ask for password if not configured
|
||||
ask_password || exit 1
|
||||
|
||||
# If no backup specified, list available ones
|
||||
if [[ -z "$BACKUP_FILE" ]]; then
|
||||
log INFO "Searching for backups in ${BACKUP_DIR}..."
|
||||
|
||||
if [[ ! -d "$BACKUP_DIR" ]]; then
|
||||
log ERROR "Backup directory not found: $BACKUP_DIR"
|
||||
log INFO "Run first: ./backup-rocknix.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUPS=($(find "$BACKUP_DIR" -name "rocknix-config-*.tar.gz" -type f | sort -r))
|
||||
|
||||
if [[ ${#BACKUPS[@]} -eq 0 ]]; then
|
||||
log ERROR "No backups found in ${BACKUP_DIR}"
|
||||
log INFO "Run first: ./backup-rocknix.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${CYAN}Available backups:${NC}"
|
||||
echo ""
|
||||
|
||||
for i in "${!BACKUPS[@]}"; do
|
||||
local backup="${BACKUPS[$i]}"
|
||||
local name=$(basename "$backup")
|
||||
local size=$(du -h "$backup" | cut -f1)
|
||||
local date=$(stat -c %y "$backup" 2>/dev/null | cut -d'.' -f1)
|
||||
|
||||
echo -e " ${GREEN}$((i+1))${NC}) ${name}"
|
||||
echo -e " Size: ${size} | Date: ${date}"
|
||||
done
|
||||
|
||||
echo ""
|
||||
read -p "Select backup (1-${#BACKUPS[@]}): " choice
|
||||
|
||||
if [[ "$choice" -lt 1 || "$choice" -gt ${#BACKUPS[@]} ]]; then
|
||||
log ERROR "Invalid selection"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
BACKUP_FILE="${BACKUPS[$((choice-1))]}"
|
||||
fi
|
||||
|
||||
# Verify backup file exists
|
||||
if [[ ! -f "$BACKUP_FILE" ]]; then
|
||||
log ERROR "Backup file not found: $BACKUP_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Show backup contents
|
||||
show_backup_contents "$BACKUP_FILE"
|
||||
|
||||
# Verify connection with target console
|
||||
echo ""
|
||||
ssh_check "$ROCKNIX_HOST" "$ROCKNIX_USER" || exit 1
|
||||
|
||||
# Detect target device
|
||||
DEVICE=$(detect_device "$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null || echo "unknown")
|
||||
log INFO "Target device: ${DEVICE}"
|
||||
|
||||
# Check backup type
|
||||
BACKUP_NAME=$(basename "$BACKUP_FILE")
|
||||
if [[ "$BACKUP_NAME" == *"generic"* ]]; then
|
||||
log WARN "This is a GENERIC backup (without device-specific settings)"
|
||||
log WARN "Make sure the target device is compatible"
|
||||
echo ""
|
||||
read -p "Continue? (y/N): " confirm
|
||||
if [[ "$confirm" != "s" && "$confirm" != "S" ]]; then
|
||||
log INFO "Restore cancelled"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create temporary directory
|
||||
TMP_DIR=$(create_tmp_dir "rocknix-restore")
|
||||
trap 'cleanup_tmp "$TMP_DIR"' EXIT
|
||||
|
||||
# Extract backup
|
||||
log INFO "Extracting backup..."
|
||||
tar -xzf "$BACKUP_FILE" -C "$TMP_DIR"
|
||||
|
||||
# Select components to restore
|
||||
if [[ "$RESTORE_ALL" == "false" ]]; then
|
||||
echo ""
|
||||
echo -e "${CYAN}Which components do you want to restore?${NC}"
|
||||
echo ""
|
||||
|
||||
COMPONENTS=(
|
||||
"retroarch-core-options:RetroArch core-options"
|
||||
"retroarch-opt:RetroArch .opt (core options)"
|
||||
"retroarch-rmp:RetroArch .rmp (remaps)"
|
||||
"retroarch-config:RetroArch overrides (config/)"
|
||||
"shaders:Shaders"
|
||||
"ppsspp:PPSSPP"
|
||||
"drastic:DraStic"
|
||||
"other-emu:Other emulators"
|
||||
)
|
||||
|
||||
SELECTION=()
|
||||
|
||||
for i in "${!COMPONENTS[@]}"; do
|
||||
IFS=':' read -r key label <<< "${COMPONENTS[$i]}"
|
||||
|
||||
# Determine if there are files of this type
|
||||
case "$key" in
|
||||
retroarch-core-options)
|
||||
[[ -f "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" ]] && available=true || available=false
|
||||
;;
|
||||
retroarch-opt)
|
||||
find "${TMP_DIR}/.config/retroarch/" -maxdepth 1 -name "*.opt" -type f 2>/dev/null | grep -q . && available=true || available=false
|
||||
;;
|
||||
retroarch-rmp)
|
||||
find "${TMP_DIR}/.config/retroarch/" -maxdepth 1 -name "*.rmp" -type f 2>/dev/null | grep -q . && available=true || available=false
|
||||
;;
|
||||
retroarch-config)
|
||||
[[ -d "${TMP_DIR}/.config/retroarch/config/" ]] && available=true || available=false
|
||||
;;
|
||||
shaders)
|
||||
[[ -d "${TMP_DIR}/shaders/" ]] && available=true || available=false
|
||||
;;
|
||||
ppsspp)
|
||||
[[ -f "${TMP_DIR}/.config/ppsspp/PSP/SYSTEM/ppsspp.ini" ]] && available=true || available=false
|
||||
;;
|
||||
drastic)
|
||||
[[ -d "${TMP_DIR}/.config/drastic/config/" ]] && available=true || available=false
|
||||
;;
|
||||
other-emu)
|
||||
[[ -d "${TMP_DIR}/.config/game/" ]] || \
|
||||
[[ -d "${TMP_DIR}/.config/flycast/" ]] || \
|
||||
[[ -f "${TMP_DIR}/.config/duckstation/settings.ini" ]] || \
|
||||
[[ -f "${TMP_DIR}/.config/yabasanshiro/.config" ]] && available=true || available=false
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$available" == "true" ]]; then
|
||||
SELECTION+=("$key" "$label" "on")
|
||||
else
|
||||
SELECTION+=("$key" "$label" "off")
|
||||
fi
|
||||
done
|
||||
|
||||
CHOICES=$(dialog --checklist "Components to restore:" \
|
||||
20 60 12 \
|
||||
"${SELECTION[@]}" \
|
||||
3>&1 1>&2 2>&3)
|
||||
|
||||
# If user cancels
|
||||
if [[ $? -ne 0 ]]; then
|
||||
log INFO "Restore cancelled"
|
||||
exit 0
|
||||
fi
|
||||
else
|
||||
# Restore all
|
||||
CHOICES="retroarch-core-options retroarch-opt retroarch-rmp retroarch-config shaders ppsspp drastic other-emu"
|
||||
fi
|
||||
|
||||
# Confirm restore
|
||||
echo ""
|
||||
echo -e "${YELLOW}Restore the following components on ${ROCKNIX_HOST}?${NC}"
|
||||
for choice in $CHOICES; do
|
||||
case "$choice" in
|
||||
retroarch-core-options) echo " - RetroArch core-options" ;;
|
||||
retroarch-opt) echo " - RetroArch .opt" ;;
|
||||
retroarch-rmp) echo " - RetroArch .rmp" ;;
|
||||
retroarch-config) echo " - RetroArch overrides" ;;
|
||||
shaders) echo " - Shaders" ;;
|
||||
ppsspp) echo " - PPSSPP" ;;
|
||||
drastic) echo " - DraStic" ;;
|
||||
other-emu) echo " - Other emulators" ;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo ""
|
||||
read -p "Confirm restore? (y/N): " confirm
|
||||
if [[ "$confirm" != "s" && "$confirm" != "S" ]]; then
|
||||
log INFO "Restore cancelled"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Create safety backup on target console
|
||||
log INFO "Creating safety backup on console..."
|
||||
SAFETY_DIR="${TMP_DIR}/safety"
|
||||
mkdir -p "$SAFETY_DIR"
|
||||
|
||||
# Download current files before overwriting
|
||||
for choice in $CHOICES; do
|
||||
case "$choice" in
|
||||
retroarch-core-options)
|
||||
download_file ".config/retroarch/retroarch-core-options.cfg" \
|
||||
"${SAFETY_DIR}/retroarch-core-options.cfg" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null || true
|
||||
;;
|
||||
# Add others if needed
|
||||
esac
|
||||
done
|
||||
|
||||
log INFO "Safety backup created"
|
||||
|
||||
# Restore files
|
||||
log INFO "Restoring files..."
|
||||
RESTORED=0
|
||||
FAILED=0
|
||||
|
||||
for choice in $CHOICES; do
|
||||
log INFO "Restoring: ${choice}..."
|
||||
|
||||
case "$choice" in
|
||||
retroarch-core-options)
|
||||
if [[ -f "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" ]]; then
|
||||
if upload_file "${TMP_DIR}/.config/retroarch/retroarch-core-options.cfg" \
|
||||
".config/retroarch/retroarch-core-options.cfg" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
log WARN "Error restoring retroarch-core-options.cfg"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
retroarch-opt)
|
||||
for opt_file in "${TMP_DIR}/.config/retroarch/"*.opt; do
|
||||
if [[ -f "$opt_file" ]]; then
|
||||
filename=$(basename "$opt_file")
|
||||
if upload_file "$opt_file" \
|
||||
".config/retroarch/${filename}" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
retroarch-rmp)
|
||||
for rmp_file in "${TMP_DIR}/.config/retroarch/"*.rmp; do
|
||||
if [[ -f "$rmp_file" ]]; then
|
||||
filename=$(basename "$rmp_file")
|
||||
if upload_file "$rmp_file" \
|
||||
".config/retroarch/${filename}" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
retroarch-config)
|
||||
if [[ -d "${TMP_DIR}/.config/retroarch/config/" ]]; then
|
||||
if upload_dir "${TMP_DIR}/.config/retroarch/config/" \
|
||||
".config/retroarch/config/" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
log WARN "Error restoring config/"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
shaders)
|
||||
if [[ -d "${TMP_DIR}/shaders/" ]]; then
|
||||
if upload_dir "${TMP_DIR}/shaders/" \
|
||||
"shaders/" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
log WARN "Error restoring shaders/"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
ppsspp)
|
||||
if [[ -f "${TMP_DIR}/.config/ppsspp/PSP/SYSTEM/ppsspp.ini" ]]; then
|
||||
upload_file "${TMP_DIR}/.config/ppsspp/PSP/SYSTEM/ppsspp.ini" \
|
||||
".config/ppsspp/PSP/SYSTEM/ppsspp.ini" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null && RESTORED=$((RESTORED + 1)) || FAILED=$((FAILED + 1))
|
||||
fi
|
||||
if [[ -f "${TMP_DIR}/.config/ppsspp/PSP/SYSTEM/controls.ini" ]]; then
|
||||
upload_file "${TMP_DIR}/.config/ppsspp/PSP/SYSTEM/controls.ini" \
|
||||
".config/ppsspp/PSP/SYSTEM/controls.ini" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null && RESTORED=$((RESTORED + 1)) || FAILED=$((FAILED + 1))
|
||||
fi
|
||||
;;
|
||||
drastic)
|
||||
if [[ -d "${TMP_DIR}/.config/drastic/config/" ]]; then
|
||||
if upload_dir "${TMP_DIR}/.config/drastic/config/" \
|
||||
".config/drastic/config/" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" &>/dev/null; then
|
||||
RESTORED=$((RESTORED + 1))
|
||||
else
|
||||
FAILED=$((FAILED + 1))
|
||||
log WARN "Error restoring drastic/config/"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
other-emu)
|
||||
for emu_path in ".config/game/configs" ".config/flycast" ".config/duckstation" ".config/yabasanshiro"; do
|
||||
if [[ -e "${TMP_DIR}/${emu_path}" ]]; then
|
||||
upload_dir "${TMP_DIR}/${emu_path}/" "${emu_path}/" \
|
||||
"$ROCKNIX_HOST" "$ROCKNIX_USER" 2>/dev/null && RESTORED=$((RESTORED + 1)) || FAILED=$((FAILED + 1))
|
||||
fi
|
||||
done
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Clean up temporary safety backup
|
||||
cleanup_tmp "${SAFETY_DIR}" 2>/dev/null || true
|
||||
|
||||
# Summary
|
||||
echo ""
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo -e "${GREEN} Restore completed${NC}"
|
||||
echo -e "${GREEN}========================================${NC}"
|
||||
echo ""
|
||||
echo -e " Device: ${CYAN}${DEVICE}${NC}"
|
||||
echo -e " Restored: ${CYAN}${RESTORED}${NC}"
|
||||
if [[ $FAILED -gt 0 ]]; then
|
||||
echo -e " Failed: ${RED}${FAILED}${NC}"
|
||||
fi
|
||||
echo ""
|
||||
echo -e " ${YELLOW}Note: Restart the console to apply changes${NC}"
|
||||
echo ""
|
||||
Reference in New Issue
Block a user