Files
maps-saas/infrastructure/scripts/restore_sovereign_map.sh
T

185 lines
8.6 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# ==============================================================================
# Sovereign Map Platform - Full Autonomous Restoration System
# منصة الخرائط السيادية - نظام الاستعادة الشامل وإعادة التشغيل على سيرفر جديد
# ==============================================================================
# Architect: Hamza Ayed - Founding Tech Architect & Sovereign Mobility Strategist
# ==============================================================================
set -euo pipefail
# ANSI Color Codes
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
CYAN='\033[0;36m'
NC='\033[0m'
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
echo -e "${CYAN}==================================================================${NC}"
echo -e "${CYAN} 🛡️ منصة خرائط سيرو السيادية | معالج استعادة النظام والسيرفر${NC}"
echo -e "${CYAN}==================================================================${NC}"
if [ $# -lt 1 ]; then
echo -e "${RED}❌ خطأ: يرجى تحديد مسار ملف النسخة الاحتياطية (.tar.gz) أو مجلد النسخة.${NC}"
echo -e "الاستخدام: $0 <path_to_backup.tar.gz | path_to_backup_dir>"
echo -e "مثال: $0 /home/hamzadoctor/backups/sovereign_map_full_backup_20260926_120000.tar.gz"
exit 1
fi
INPUT_PATH="$1"
TEMP_RESTORE_DIR=""
# Determine whether input is a tarball or a directory
if [ -f "$INPUT_PATH" ] && [[ "$INPUT_PATH" == *.tar.gz ]]; then
echo -e "📦 تم التعرف على ملف أرشيف مضغوط: ${YELLOW}$INPUT_PATH${NC}"
TEMP_RESTORE_DIR=$(mktemp -d /tmp/sovereign_restore_XXXXXX)
echo -e "⏳ جاري فك ضغط الأرشيف إلى: ${CYAN}$TEMP_RESTORE_DIR${NC}..."
tar -xzf "$INPUT_PATH" -C "$TEMP_RESTORE_DIR"
# Find the unpacked inner folder
RESTORE_SRC=$(find "$TEMP_RESTORE_DIR" -maxdepth 1 -mindepth 1 -type d | head -n 1)
if [ -z "$RESTORE_SRC" ]; then
RESTORE_SRC="$TEMP_RESTORE_DIR"
fi
elif [ -d "$INPUT_PATH" ]; then
echo -e "📁 تم التعرف على مجلد نسخة احتياطية: ${YELLOW}$INPUT_PATH${NC}"
RESTORE_SRC="$INPUT_PATH"
else
echo -e "${RED}❌ المسار المحدد غير صالح: $INPUT_PATH${NC}"
exit 1
fi
echo -e "🔍 فحص مكونات النسخة الاحتياطية في: ${GREEN}$RESTORE_SRC${NC}"
# Check for database dump
DUMP_FILE="$RESTORE_SRC/database/mapdb_custom.dump"
SQL_FILE="$RESTORE_SRC/database/mapdb_schema.sql"
if [ ! -f "$DUMP_FILE" ] && [ ! -f "$SQL_FILE" ]; then
echo -e "${RED}❌ لم يتم العثور على ملفات قاعدة البيانات (mapdb_custom.dump أو mapdb_schema.sql)${NC}"
exit 1
fi
# Step 1: Ensure Docker is active
echo -e "\n${BLUE}[1/6] 🐳 فحص بيئة Docker و Docker Compose...${NC}"
if ! command -v docker &> /dev/null; then
echo -e "${RED}❌ Docker غير مثبت على هذا السيرفر! يرجى تثبيته أولاً.${NC}"
exit 1
fi
DOCKER_COMPOSE_CMD=""
if docker compose version &> /dev/null; then
DOCKER_COMPOSE_CMD="docker compose"
elif command -v docker-compose &> /dev/null; then
DOCKER_COMPOSE_CMD="docker-compose"
else
echo -e "${RED}❌ docker compose غير متاح!${NC}"
exit 1
fi
echo -e " ✅ محرك الحاويات جاهز: ${GREEN}$($DOCKER_COMPOSE_CMD version --short)${NC}"
# Step 2: Check & prepare .env file
echo -e "\n${BLUE}[2/6] ⚙️ تهيئة متغيرات البيئة (.env)...${NC}"
cd "$ROOT_DIR"
if [ ! -f "$ROOT_DIR/.env" ] && [ -f "$RESTORE_SRC/configs/.env.backup" ]; then
echo -e " 📥 استعادة ملف .env من النسخة الاحتياطية..."
cp "$RESTORE_SRC/configs/.env.backup" "$ROOT_DIR/.env"
elif [ -f "$ROOT_DIR/.env" ]; then
echo -e " ✅ ملف .env موجود مسبقاً في مسار المشروع."
else
echo -e " ${YELLOW}⚠️ لم يوجد .env! يرجى إنشاء ملف .env بالاعتماد على .env.example${NC}"
fi
# Step 3: Restore offline MBTiles & OSM packages
echo -e "\n${BLUE}[3/6] 🗺️ استعادة المربعات السيادية وحزم التوجيه (Offline Datasets)...${NC}"
if [ -d "$RESTORE_SRC/geodata/mbtiles" ]; then
mkdir -p "$ROOT_DIR/data/mbtiles"
echo -e " 📥 استعادة ملفات الارتفاع والأقمار الصناعية (MBTiles)..."
cp -rf "$RESTORE_SRC/geodata/mbtiles/"* "$ROOT_DIR/data/mbtiles/" 2>/dev/null || true
fi
if [ -f "$RESTORE_SRC/geodata/jordan-latest.osm.pbf" ]; then
mkdir -p "$ROOT_DIR/infrastructure/osm-data"
echo -e " 📥 استعادة ملف خريطة الأردن الخام (OSM PBF)..."
cp -f "$RESTORE_SRC/geodata/jordan-latest.osm.pbf" "$ROOT_DIR/infrastructure/osm-data/"
fi
if [ -d "$RESTORE_SRC/geodata/routing-packages" ]; then
mkdir -p "$ROOT_DIR/infrastructure/osm-data/routing-packages"
echo -e " 📥 استعادة حزم التوجيه المحلية (Valhalla routing)..."
cp -rf "$RESTORE_SRC/geodata/routing-packages/"* "$ROOT_DIR/infrastructure/osm-data/routing-packages/" 2>/dev/null || true
fi
# Step 4: Boot Database & Redis Containers
echo -e "\n${BLUE}[4/6] 🐘 تشغيل حاويات الداتابيز والكاش والتأكد من جاهزيتها...${NC}"
$DOCKER_COMPOSE_CMD up -d db redis
echo -e " ⏳ في انتظار جاهزية PostgreSQL و PostGIS..."
for i in {1..30}; do
if docker exec map-db pg_isready -U mapuser -d mapdb &>/dev/null; then
echo -e " ✅ قاعدة البيانات PostGIS جاهزة للحقن!"
break
fi
sleep 2
if [ $i -eq 30 ]; then
echo -e "${RED}❌ فشل انتظار جاهزية قاعدة البيانات! تفقد سجلات docker logs map-db${NC}"
exit 1
fi
done
# Step 5: Inject PostGIS Database
echo -e "\n${BLUE}[5/6] 📥 استعادة وحقن البيانات المكانية في PostGIS...${NC}"
if [ -f "$DUMP_FILE" ]; then
echo -e " ⏳ جاري الاستعادة من ملف الـ Custom Dump المسرّع..."
# Ensure postgis extension exists
docker exec -i map-db psql -U mapuser -d mapdb -c "CREATE EXTENSION IF NOT EXISTS postgis;"
docker exec -i map-db psql -U mapuser -d mapdb -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;"
# Restore dump (ignore non-fatal warnings for clean recreation)
docker exec -i map-db pg_restore -U mapuser -d mapdb --clean --if-exists --no-owner --no-acl < "$DUMP_FILE" || true
# Run VACUUM ANALYZE to optimize geometry indices
echo -e " ⚡ تحسين الفهارس المكانية (VACUUM ANALYZE)..."
docker exec -i map-db psql -U mapuser -d mapdb -c "VACUUM ANALYZE;"
echo -e " ✅ تم استعادة قاعدة البيانات وتحديث الفهارس بنجاح!"
fi
# Step 6: Start Full Application Stack & Healthcheck
echo -e "\n${BLUE}[6/6] 🚀 بناء وتشغيل كافة خدمات المنصة السيادية...${NC}"
$DOCKER_COMPOSE_CMD up -d --build api martin web dashboard routing
echo -e "\n⏳ فحص صحة الخدمات (Health Checks)..."
sleep 5
check_service() {
local name="$1"
local url="$2"
if curl -s -f -m 5 "$url" > /dev/null 2>&1; then
echo -e " ✅ خدمة ${GREEN}$name${NC} تعمل بنجاح: $url"
else
echo -e " ℹ️ خدمة ${YELLOW}$name${NC} في طور الإقلاع أو تتطلب ثوانٍ إضافية: $url"
fi
}
check_service "Backend API (NestJS)" "http://localhost:3200/api/health"
check_service "Martin Vector Tiles" "http://localhost:3202/health"
check_service "GraphHopper Routing" "http://localhost:8989/health"
check_service "Web Tactical Portal" "http://localhost:3201"
check_service "Developer Dashboard" "http://localhost:3204"
# Cleanup temp unpack dir if created
if [ -n "$TEMP_RESTORE_DIR" ] && [ -d "$TEMP_RESTORE_DIR" ]; then
rm -rf "$TEMP_RESTORE_DIR"
fi
echo -e "\n${GREEN}==================================================================${NC}"
echo -e "${GREEN} 🎉 اكتملت عملية الاستعادة بنجاح والمنصة تعمل بكامل طاقتها!${NC}"
echo -e "${GREEN}==================================================================${NC}"
echo -e "🌐 البوابة التكتيكية والمناورة: http://localhost:3201/#maneuver"
echo -e "📡 خادم الخرائط السيادي (Martin): http://localhost:3202"
echo -e "⚡ محرك التوجيه (GraphHopper): http://localhost:8989"
echo -e "💼 لوحة المطورين والإدارة: http://localhost:3204"
echo -e "------------------------------------------------------------------"