#!/usr/bin/env python3 """ Gestionnaire de lancement unifié pour RPA Vision V3 Unifie l'environnement vers la production systemd avec synchronisation des données """ import os import sys import json import shutil import subprocess from pathlib import Path from datetime import datetime from typing import Dict, List, Optional class UnifiedLaunchManager: """Gestionnaire unifié pour le lancement de RPA Vision V3""" def __init__(self): self.local_root = Path.cwd() self.prod_root = Path("/opt/rpa_vision_v3") self.services = [ "rpa-vision-v3-api.service", "rpa-vision-v3-dashboard.service", "rpa-vision-v3-worker.service" ] def print_status(self, message: str, status: str = "INFO"): """Affiche un message avec couleur""" colors = { "INFO": "\033[0;34m", # Bleu "SUCCESS": "\033[0;32m", # Vert "WARNING": "\033[1;33m", # Jaune "ERROR": "\033[0;31m", # Rouge "RESET": "\033[0m" # Reset } print(f"{colors.get(status, '')}{message}{colors['RESET']}") def check_systemd_services(self) -> Dict[str, bool]: """Vérifie l'état des services systemd""" status = {} for service in self.services: try: result = subprocess.run( ["sudo", "systemctl", "is-active", service], capture_output=True, text=True ) status[service] = result.returncode == 0 except Exception: status[service] = False return status def stop_systemd_services(self): """Arrête tous les services systemd""" self.print_status("🛑 Arrêt des services systemd...", "WARNING") for service in self.services: try: subprocess.run(["sudo", "systemctl", "stop", service], check=True) self.print_status(f"✓ Service {service} arrêté", "SUCCESS") except subprocess.CalledProcessError: self.print_status(f"⚠ Impossible d'arrêter {service}", "WARNING") def start_systemd_services(self): """Démarre tous les services systemd""" self.print_status("🚀 Démarrage des services systemd...", "INFO") for service in self.services: try: subprocess.run(["sudo", "systemctl", "start", service], check=True) self.print_status(f"✓ Service {service} démarré", "SUCCESS") except subprocess.CalledProcessError: self.print_status(f"❌ Échec du démarrage de {service}", "ERROR") def sync_data_to_production(self): """Synchronise les données locales vers la production""" self.print_status("📂 Synchronisation des données vers la production...", "INFO") local_data = self.local_root / "data" prod_data = self.prod_root / "data" if not local_data.exists(): self.print_status("⚠ Aucune donnée locale à synchroniser", "WARNING") return # Créer une sauvegarde des données de production if prod_data.exists(): backup_path = self.prod_root / f"data_backup_{datetime.now().strftime('%Y%m%d_%H%M%S')}" self.print_status(f"💾 Sauvegarde des données prod vers {backup_path}", "INFO") try: subprocess.run(["sudo", "cp", "-r", str(prod_data), str(backup_path)], check=True) except subprocess.CalledProcessError: self.print_status("❌ Échec de la sauvegarde", "ERROR") return # Synchroniser les données try: # Copier les sessions local_sessions = local_data / "training" / "sessions" prod_sessions = prod_data / "training" / "sessions" if local_sessions.exists(): subprocess.run(["sudo", "mkdir", "-p", str(prod_sessions.parent)], check=True) subprocess.run(["sudo", "cp", "-r", str(local_sessions), str(prod_sessions.parent)], check=True) subprocess.run(["sudo", "chown", "-R", "rpa:rpa", str(prod_data)], check=True) self.print_status("✓ Sessions synchronisées", "SUCCESS") # Copier les workflows local_workflows = local_data / "workflows" prod_workflows = prod_data / "workflows" if local_workflows.exists(): subprocess.run(["sudo", "cp", "-r", str(local_workflows), str(prod_workflows.parent)], check=True) subprocess.run(["sudo", "chown", "-R", "rpa:rpa", str(prod_workflows)], check=True) self.print_status("✓ Workflows synchronisés", "SUCCESS") except subprocess.CalledProcessError as e: self.print_status(f"❌ Erreur de synchronisation: {e}", "ERROR") def sync_data_from_production(self): """Synchronise les données de production vers local (pour développement)""" self.print_status("📂 Synchronisation des données depuis la production...", "INFO") local_data = self.local_root / "data" prod_data = self.prod_root / "data" if not prod_data.exists(): self.print_status("⚠ Aucune donnée de production à synchroniser", "WARNING") return try: # Créer le répertoire local si nécessaire local_data.mkdir(exist_ok=True) # Copier les sessions prod_sessions = prod_data / "training" / "sessions" local_sessions = local_data / "training" / "sessions" if prod_sessions.exists(): local_sessions.parent.mkdir(parents=True, exist_ok=True) subprocess.run(["sudo", "cp", "-r", str(prod_sessions), str(local_sessions.parent)], check=True) subprocess.run(["sudo", "chown", "-R", f"{os.getenv('USER')}:{os.getenv('USER')}", str(local_sessions)], check=True) self.print_status("✓ Sessions copiées depuis la production", "SUCCESS") # Copier les workflows prod_workflows = prod_data / "workflows" local_workflows = local_data / "workflows" if prod_workflows.exists(): subprocess.run(["sudo", "cp", "-r", str(prod_workflows), str(local_workflows.parent)], check=True) subprocess.run(["sudo", "chown", "-R", f"{os.getenv('USER')}:{os.getenv('USER')}", str(local_workflows)], check=True) self.print_status("✓ Workflows copiés depuis la production", "SUCCESS") except subprocess.CalledProcessError as e: self.print_status(f"❌ Erreur de synchronisation: {e}", "ERROR") def show_service_status(self): """Affiche l'état des services""" self.print_status("📊 État des services RPA Vision V3", "INFO") print() status = self.check_systemd_services() for service, is_active in status.items(): status_text = "🟢 ACTIF" if is_active else "🔴 ARRÊTÉ" self.print_status(f" {service}: {status_text}") print() self.print_status("🌐 URLs d'accès:", "INFO") self.print_status(" API Server: http://localhost:8000") self.print_status(" Dashboard: http://localhost:5001") print() def show_data_info(self): """Affiche les informations sur les données""" self.print_status("📂 Informations sur les données", "INFO") print() # Données locales local_sessions = self.local_root / "data" / "training" / "sessions" if local_sessions.exists(): local_count = len(list(local_sessions.iterdir())) self.print_status(f" Données locales: {local_count} sessions dans {local_sessions}") else: self.print_status(" Données locales: Aucune") # Données de production prod_sessions = self.prod_root / "data" / "training" / "sessions" if prod_sessions.exists(): try: result = subprocess.run(["sudo", "ls", str(prod_sessions)], capture_output=True, text=True) prod_count = len(result.stdout.strip().split('\n')) if result.stdout.strip() else 0 self.print_status(f" Données production: {prod_count} sessions dans {prod_sessions}") except: self.print_status(" Données production: Erreur d'accès") else: self.print_status(" Données production: Aucune") print() def unified_start(self): """Démarrage unifié en mode production""" self.print_status("🎼 RPA Vision V3 - Démarrage Unifié (Production)", "INFO") print() # 1. Synchroniser les données vers la production self.sync_data_to_production() print() # 2. Démarrer les services systemd self.start_systemd_services() print() # 3. Attendre que les services démarrent self.print_status("⏳ Attente du démarrage des services...", "INFO") import time time.sleep(5) # 4. Afficher le statut final self.show_service_status() def unified_stop(self): """Arrêt unifié""" self.print_status("🛑 RPA Vision V3 - Arrêt Unifié", "WARNING") print() # Arrêter les services systemd self.stop_systemd_services() print() # Synchroniser les données vers local pour développement self.sync_data_from_production() print() self.print_status("✓ Arrêt complet terminé", "SUCCESS") def unified_restart(self): """Redémarrage unifié""" self.print_status("🔄 RPA Vision V3 - Redémarrage Unifié", "INFO") print() self.unified_stop() print() self.unified_start() def main(): """Point d'entrée principal""" manager = UnifiedLaunchManager() if len(sys.argv) < 2: print("Usage: python unified_launch_manager.py [start|stop|restart|status|sync-to-prod|sync-from-prod]") sys.exit(1) command = sys.argv[1] if command == "start": manager.unified_start() elif command == "stop": manager.unified_stop() elif command == "restart": manager.unified_restart() elif command == "status": manager.show_service_status() manager.show_data_info() elif command == "sync-to-prod": manager.sync_data_to_production() elif command == "sync-from-prod": manager.sync_data_from_production() else: print(f"Commande inconnue: {command}") sys.exit(1) if __name__ == "__main__": main()