🎉 Refactor and optimize database files, enhance error handling with new utility scripts 📚, and update documentation on fault tolerance and unattended operation. 🚀

This commit is contained in:
2025-06-02 14:57:58 +02:00
parent 7bea427bd6
commit 6ff407a895
29 changed files with 3148 additions and 450 deletions

View File

@@ -1241,6 +1241,239 @@ def kiosk_restart_system():
kiosk_logger.error(f"Fehler beim System-Neustart: {str(e)}")
return jsonify({"error": "Fehler beim Neustart"}), 500
# ===== ERWEITERTE SYSTEM-CONTROL API-ENDPUNKTE =====
@app.route('/api/admin/system/restart', methods=['POST'])
@login_required
@admin_required
def api_admin_system_restart():
"""Robuster System-Neustart mit Sicherheitsprüfungen."""
try:
from utils.system_control import schedule_system_restart
data = request.get_json() or {}
delay_seconds = data.get('delay_seconds', 60)
reason = data.get('reason', 'Manueller Admin-Neustart')
force = data.get('force', False)
# Begrenze Verzögerung auf sinnvolle Werte
delay_seconds = max(10, min(3600, delay_seconds)) # 10s bis 1h
result = schedule_system_restart(
delay_seconds=delay_seconds,
user_id=str(current_user.id),
reason=reason,
force=force
)
if result.get('success'):
app_logger.warning(f"System-Neustart geplant von Admin {current_user.username}: {reason}")
return jsonify(result)
else:
return jsonify(result), 400
except Exception as e:
app_logger.error(f"Fehler bei System-Neustart-Planung: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/system/shutdown', methods=['POST'])
@login_required
@admin_required
def api_admin_system_shutdown():
"""Robuster System-Shutdown mit Sicherheitsprüfungen."""
try:
from utils.system_control import schedule_system_shutdown
data = request.get_json() or {}
delay_seconds = data.get('delay_seconds', 30)
reason = data.get('reason', 'Manueller Admin-Shutdown')
force = data.get('force', False)
# Begrenze Verzögerung auf sinnvolle Werte
delay_seconds = max(10, min(3600, delay_seconds)) # 10s bis 1h
result = schedule_system_shutdown(
delay_seconds=delay_seconds,
user_id=str(current_user.id),
reason=reason,
force=force
)
if result.get('success'):
app_logger.warning(f"System-Shutdown geplant von Admin {current_user.username}: {reason}")
return jsonify(result)
else:
return jsonify(result), 400
except Exception as e:
app_logger.error(f"Fehler bei System-Shutdown-Planung: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/kiosk/restart', methods=['POST'])
@login_required
@admin_required
def api_admin_kiosk_restart():
"""Kiosk-Display neustarten ohne System-Neustart."""
try:
from utils.system_control import restart_kiosk
data = request.get_json() or {}
delay_seconds = data.get('delay_seconds', 10)
reason = data.get('reason', 'Manueller Kiosk-Neustart')
# Begrenze Verzögerung
delay_seconds = max(0, min(300, delay_seconds)) # 0s bis 5min
result = restart_kiosk(
delay_seconds=delay_seconds,
user_id=str(current_user.id),
reason=reason
)
if result.get('success'):
app_logger.info(f"Kiosk-Neustart geplant von Admin {current_user.username}: {reason}")
return jsonify(result)
else:
return jsonify(result), 400
except Exception as e:
app_logger.error(f"Fehler bei Kiosk-Neustart-Planung: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/system/status', methods=['GET'])
@login_required
@admin_required
def api_admin_system_status_extended():
"""Erweiterte System-Status-Informationen."""
try:
from utils.system_control import get_system_status
from utils.error_recovery import get_error_recovery_manager
# System-Control-Status
system_status = get_system_status()
# Error-Recovery-Status
error_manager = get_error_recovery_manager()
error_stats = error_manager.get_error_statistics()
# Kombiniere alle Informationen
combined_status = {
**system_status,
"error_recovery": error_stats,
"resilience_features": {
"auto_recovery_enabled": error_stats.get('auto_recovery_enabled', False),
"monitoring_active": error_stats.get('monitoring_active', False),
"recovery_success_rate": error_stats.get('recovery_success_rate', 0)
}
}
return jsonify(combined_status)
except Exception as e:
app_logger.error(f"Fehler bei System-Status-Abfrage: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/system/operations', methods=['GET'])
@login_required
@admin_required
def api_admin_system_operations():
"""Gibt geplante und vergangene System-Operationen zurück."""
try:
from utils.system_control import get_system_control_manager
manager = get_system_control_manager()
return jsonify({
"success": True,
"pending_operations": manager.get_pending_operations(),
"operation_history": manager.get_operation_history(limit=50)
})
except Exception as e:
app_logger.error(f"Fehler bei Operations-Abfrage: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/system/operations/<operation_id>/cancel', methods=['POST'])
@login_required
@admin_required
def api_admin_cancel_operation(operation_id):
"""Bricht geplante System-Operation ab."""
try:
from utils.system_control import get_system_control_manager
manager = get_system_control_manager()
result = manager.cancel_operation(operation_id)
if result.get('success'):
app_logger.info(f"Operation {operation_id} abgebrochen von Admin {current_user.username}")
return jsonify(result)
else:
return jsonify(result), 400
except Exception as e:
app_logger.error(f"Fehler beim Abbrechen von Operation {operation_id}: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/error-recovery/status', methods=['GET'])
@login_required
@admin_required
def api_admin_error_recovery_status():
"""Gibt Error-Recovery-Status und -Statistiken zurück."""
try:
from utils.error_recovery import get_error_recovery_manager
manager = get_error_recovery_manager()
return jsonify({
"success": True,
"statistics": manager.get_error_statistics(),
"recent_errors": manager.get_recent_errors(limit=20)
})
except Exception as e:
app_logger.error(f"Fehler bei Error-Recovery-Status-Abfrage: {e}")
return jsonify({"success": False, "error": str(e)}), 500
@app.route('/api/admin/error-recovery/toggle', methods=['POST'])
@login_required
@admin_required
def api_admin_toggle_error_recovery():
"""Aktiviert/Deaktiviert Error-Recovery-Monitoring."""
try:
from utils.error_recovery import get_error_recovery_manager
data = request.get_json() or {}
enable = data.get('enable', True)
manager = get_error_recovery_manager()
if enable:
manager.start_monitoring()
message = "Error-Recovery-Monitoring aktiviert"
else:
manager.stop_monitoring()
message = "Error-Recovery-Monitoring deaktiviert"
app_logger.info(f"{message} von Admin {current_user.username}")
return jsonify({
"success": True,
"message": message,
"monitoring_active": manager.is_active
})
except Exception as e:
app_logger.error(f"Fehler beim Toggle von Error-Recovery: {e}")
return jsonify({"success": False, "error": str(e)}), 500
# ===== BENUTZER-ROUTEN (ehemals user.py) =====
@app.route("/user/profile", methods=["GET"])
@@ -8718,6 +8951,43 @@ if __name__ == "__main__":
app_logger.error(f"❌ Shutdown-Manager konnte nicht geladen werden: {e}")
# Fallback auf die alte Methode
shutdown_manager = None
# ===== INITIALISIERE FEHLERRESILIENZ-SYSTEME =====
try:
from utils.error_recovery import start_error_monitoring, stop_error_monitoring
from utils.system_control import get_system_control_manager
# Error-Recovery-Monitoring starten
start_error_monitoring()
app_logger.info("✅ Error-Recovery-Monitoring gestartet")
# System-Control-Manager initialisieren
system_control_manager = get_system_control_manager()
app_logger.info("✅ System-Control-Manager initialisiert")
# Integriere in Shutdown-Manager
if shutdown_manager:
shutdown_manager.register_cleanup_function(
func=stop_error_monitoring,
name="Error Recovery Monitoring",
priority=2,
timeout=10
)
except Exception as e:
app_logger.error(f"❌ Fehlerresilienz-Systeme konnten nicht initialisiert werden: {e}")
# ===== KIOSK-SERVICE-OPTIMIERUNG =====
try:
# Stelle sicher, dass der Kiosk-Service korrekt konfiguriert ist
kiosk_service_exists = os.path.exists('/etc/systemd/system/myp-kiosk.service')
if not kiosk_service_exists:
app_logger.warning("⚠️ Kiosk-Service nicht gefunden - Kiosk-Funktionen eventuell eingeschränkt")
else:
app_logger.info("✅ Kiosk-Service-Konfiguration gefunden")
except Exception as e:
app_logger.error(f"❌ Kiosk-Service-Check fehlgeschlagen: {e}")
# Windows-spezifisches Signal-Handling als Fallback
def fallback_signal_handler(sig, frame):