restore.sh•11.1 kB
#!/bin/bash
################################################################################
# Restore Script for KYC MCP Server
# This script restores application data from a backup
################################################################################
set -euo pipefail
# Configuration
APP_DIR="/opt/kyc-mcp-server"
BACKUP_BASE_DIR="/opt/kyc-mcp-server-backups"
S3_BUCKET="${S3_BACKUP_BUCKET:-}"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
log_step() {
echo -e "${BLUE}[STEP]${NC} $(date '+%Y-%m-%d %H:%M:%S') - $1"
}
# Error handler
error_exit() {
log_error "$1"
exit 1
}
# Show usage
show_usage() {
cat <<EOF
Usage: $0 [OPTIONS]
Restore KYC MCP Server from backup
OPTIONS:
-f, --file <path> Path to backup file (local)
-s, --s3 <key> S3 key of backup file
-l, --list List available backups
-c, --components <list> Comma-separated list of components to restore
(redis,config,logs,docker)
Default: all components
-h, --help Show this help message
EXAMPLES:
# Restore from local backup file
$0 --file /opt/kyc-mcp-server-backups/backup_20240120_120000.tar.gz
# Restore from S3
$0 --s3 kyc-mcp-server/backups/backup_20240120_120000.tar.gz
# Restore only Redis and config
$0 --file backup.tar.gz --components redis,config
# List available backups
$0 --list
EOF
}
# List available backups
list_backups() {
log_step "Available local backups:"
echo ""
if [ -d "$BACKUP_BASE_DIR" ]; then
ls -lh "$BACKUP_BASE_DIR"/backup_*.tar.gz 2>/dev/null | awk '{print $9, "(" $5 ")"}'
else
log_warn "No local backups found"
fi
echo ""
if [ -n "$S3_BUCKET" ] && command -v aws &> /dev/null; then
log_step "Available S3 backups:"
echo ""
aws s3 ls "s3://$S3_BUCKET/kyc-mcp-server/backups/" --human-readable
else
log_warn "S3 backups not available (S3_BACKUP_BUCKET not set or AWS CLI not installed)"
fi
}
# Download backup from S3
download_from_s3() {
local s3_key=$1
local local_file="$BACKUP_BASE_DIR/$(basename $s3_key)"
log_step "Downloading backup from S3..."
if ! command -v aws &> /dev/null; then
error_exit "AWS CLI not installed"
fi
if aws s3 cp "s3://$S3_BUCKET/$s3_key" "$local_file"; then
log_info "Backup downloaded: $local_file"
echo "$local_file"
else
error_exit "Failed to download backup from S3"
fi
}
# Extract backup
extract_backup() {
local backup_file=$1
local extract_dir="$BACKUP_BASE_DIR/restore_$(date +%Y%m%d_%H%M%S)"
log_step "Extracting backup..."
mkdir -p "$extract_dir"
tar -xzf "$backup_file" -C "$extract_dir" --strip-components=1
log_info "Backup extracted to: $extract_dir"
echo "$extract_dir"
}
# Verify backup
verify_backup() {
local extract_dir=$1
log_step "Verifying backup..."
if [ ! -f "$extract_dir/metadata.json" ]; then
log_warn "Backup metadata not found"
else
log_info "Backup metadata:"
cat "$extract_dir/metadata.json"
fi
# Check components
local has_redis=$([ -f "$extract_dir/redis/dump.rdb" ] && echo "yes" || echo "no")
local has_config=$([ -f "$extract_dir/config/.env" ] && echo "yes" || echo "no")
local has_logs=$([ -d "$extract_dir/logs" ] && echo "yes" || echo "no")
local has_docker=$([ -f "$extract_dir/docker/kyc-mcp-server.tar" ] && echo "yes" || echo "no")
echo ""
log_info "Backup components:"
echo " Redis data: $has_redis"
echo " Configuration: $has_config"
echo " Logs: $has_logs"
echo " Docker image: $has_docker"
echo ""
}
# Confirm restore
confirm_restore() {
echo ""
log_warn "=========================================="
log_warn "WARNING: This will overwrite current data!"
log_warn "=========================================="
echo ""
read -p "Are you sure you want to continue? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then
log_info "Restore cancelled"
exit 0
fi
}
# Stop services
stop_services() {
log_step "Stopping services..."
cd "$APP_DIR"
if docker ps | grep -q kyc-mcp-server; then
docker-compose down
log_info "Services stopped"
else
log_warn "Services not running"
fi
}
# Restore Redis data
restore_redis() {
local extract_dir=$1
log_step "Restoring Redis data..."
if [ ! -f "$extract_dir/redis/dump.rdb" ]; then
log_warn "Redis backup not found, skipping"
return 0
fi
# Start Redis container
cd "$APP_DIR"
docker-compose up -d redis
sleep 5
# Copy dump file
docker cp "$extract_dir/redis/dump.rdb" kyc-redis:/data/dump.rdb
# Copy AOF file if exists
if [ -f "$extract_dir/redis/appendonly.aof" ]; then
docker cp "$extract_dir/redis/appendonly.aof" kyc-redis:/data/appendonly.aof
fi
# Restart Redis
docker-compose restart redis
log_info "Redis data restored"
}
# Restore configuration
restore_config() {
local extract_dir=$1
log_step "Restoring configuration..."
# Backup current config
if [ -f "$APP_DIR/.env" ]; then
cp "$APP_DIR/.env" "$APP_DIR/.env.backup.$(date +%Y%m%d_%H%M%S)"
fi
# Restore .env
if [ -f "$extract_dir/config/.env" ]; then
cp "$extract_dir/config/.env" "$APP_DIR/.env"
log_info "Environment file restored"
else
log_warn ".env file not found in backup"
fi
# Restore docker-compose.yml
if [ -f "$extract_dir/config/docker-compose.yml" ]; then
cp "$extract_dir/config/docker-compose.yml" "$APP_DIR/docker-compose.yml"
log_info "Docker Compose file restored"
fi
# Restore nginx config
if [ -f "$extract_dir/config/nginx-kyc-mcp.conf" ]; then
sudo cp "$extract_dir/config/nginx-kyc-mcp.conf" /etc/nginx/sites-available/kyc-mcp.conf
sudo nginx -t && sudo systemctl reload nginx
log_info "Nginx configuration restored"
fi
# Restore systemd service
if [ -f "$extract_dir/config/kyc-mcp.service" ]; then
sudo cp "$extract_dir/config/kyc-mcp.service" /etc/systemd/system/kyc-mcp.service
sudo systemctl daemon-reload
log_info "Systemd service restored"
fi
}
# Restore logs
restore_logs() {
local extract_dir=$1
log_step "Restoring logs..."
if [ ! -d "$extract_dir/logs" ]; then
log_warn "Logs not found in backup, skipping"
return 0
fi
sudo mkdir -p /var/log/kyc-mcp-server
sudo cp -r "$extract_dir/logs/"* /var/log/kyc-mcp-server/ 2>/dev/null || log_warn "No logs to restore"
log_info "Logs restored"
}
# Restore Docker image
restore_docker() {
local extract_dir=$1
log_step "Restoring Docker image..."
if [ ! -f "$extract_dir/docker/kyc-mcp-server.tar" ]; then
log_warn "Docker image not found in backup, skipping"
return 0
fi
docker load -i "$extract_dir/docker/kyc-mcp-server.tar"
log_info "Docker image restored"
}
# Start services
start_services() {
log_step "Starting services..."
cd "$APP_DIR"
docker-compose up -d
log_info "Services started"
}
# Verify restoration
verify_restoration() {
log_step "Verifying restoration..."
sleep 10
# Check if containers are running
if docker ps | grep -q kyc-mcp-server; then
log_info "✓ Application container is running"
else
log_error "✗ Application container is not running"
fi
if docker ps | grep -q kyc-redis; then
log_info "✓ Redis container is running"
else
log_error "✗ Redis container is not running"
fi
# Check Redis connection
if docker exec kyc-redis redis-cli ping | grep -q PONG; then
log_info "✓ Redis is responding"
else
log_error "✗ Redis is not responding"
fi
}
# Main restore function
main() {
local backup_file=""
local s3_key=""
local components="redis,config,logs,docker"
local list_only=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
-f|--file)
backup_file="$2"
shift 2
;;
-s|--s3)
s3_key="$2"
shift 2
;;
-c|--components)
components="$2"
shift 2
;;
-l|--list)
list_only=true
shift
;;
-h|--help)
show_usage
exit 0
;;
*)
log_error "Unknown option: $1"
show_usage
exit 1
;;
esac
done
# List backups if requested
if [ "$list_only" = true ]; then
list_backups
exit 0
fi
# Validate input
if [ -z "$backup_file" ] && [ -z "$s3_key" ]; then
log_error "Either --file or --s3 must be specified"
show_usage
exit 1
fi
log_info "Starting restore of KYC MCP Server..."
# Download from S3 if needed
if [ -n "$s3_key" ]; then
backup_file=$(download_from_s3 "$s3_key")
fi
# Verify backup file exists
if [ ! -f "$backup_file" ]; then
error_exit "Backup file not found: $backup_file"
fi
# Extract backup
extract_dir=$(extract_backup "$backup_file")
# Verify backup
verify_backup "$extract_dir"
# Confirm restore
confirm_restore
# Stop services
stop_services
# Restore components
IFS=',' read -ra COMPONENTS <<< "$components"
for component in "${COMPONENTS[@]}"; do
case $component in
redis)
restore_redis "$extract_dir"
;;
config)
restore_config "$extract_dir"
;;
logs)
restore_logs "$extract_dir"
;;
docker)
restore_docker "$extract_dir"
;;
*)
log_warn "Unknown component: $component"
;;
esac
done
# Start services
start_services
# Verify restoration
verify_restoration
# Cleanup
rm -rf "$extract_dir"
log_info "=========================================="
log_info "Restore completed successfully!"
log_info "=========================================="
}
# Run main function
main "$@"