From d8b3214ede2cbc22c995ec5a3a70603911e95de0 Mon Sep 17 00:00:00 2001 From: pablinux Date: Wed, 21 Jan 2026 17:12:10 -0500 Subject: [PATCH] =?UTF-8?q?fix:=20Mejorar=20robustez=20del=20endpoint=20de?= =?UTF-8?q?=20eliminaci=C3=B3n=20de=20apps?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - unregister_app_handler ahora intenta eliminar de 3 fuentes: 1. AppManager (memoria) - puede fallar si app no se registró bien 2. JSON (soft delete) - marca como eliminada en monitored_apps.json 3. systemd (físico) - elimina .service, stop, disable, daemon-reload - Logs detallados en cada paso (INFO/WARNING) - Ya no falla con 'Aplicación no encontrada' si solo falta en memoria - Resuelve problema de GatewaySIGMA que no se podía eliminar - Operación best-effort: intenta todo sin fallar si un paso falla --- src/api/handlers.rs | 61 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 54 insertions(+), 7 deletions(-) diff --git a/src/api/handlers.rs b/src/api/handlers.rs index d9c6591..3531b5c 100644 --- a/src/api/handlers.rs +++ b/src/api/handlers.rs @@ -64,16 +64,63 @@ pub async fn unregister_app_handler( State(state): State>, Path(app_name): Path, ) -> Result>, StatusCode> { + use crate::config::get_config_manager; + use crate::systemd::{SystemCtl, ServiceGenerator}; + let logger = crate::logger::get_logger(); + let service_name = format!("siax-app-{}.service", app_name); + + logger.info("API", &format!("🗑️ Solicitud de eliminación para: {}", app_name)); + + // Intentar 1: Eliminar desde AppManager (si está en memoria) + let mut deleted_from_memory = false; match state.app_manager.unregister_app(&app_name) { - Ok(_) => Ok(Json(ApiResponse::success(OperationResponse { - app_name: app_name.clone(), - operation: "unregister".to_string(), - success: true, - message: "Aplicación eliminada exitosamente".to_string(), - }))), - Err(e) => Ok(Json(ApiResponse::error(e.to_string()))), + Ok(_) => { + logger.info("API", &format!("✅ Eliminado desde AppManager: {}", app_name)); + deleted_from_memory = true; + } + Err(e) => { + logger.warning("API", &format!("App no encontrada en AppManager: {}", e), None); + } } + + // Intentar 2: Soft delete en JSON (siempre intentar) + let config_manager = get_config_manager(); + let delete_reason = Some("Eliminada desde el panel de control".to_string()); + match config_manager.soft_delete_app(&app_name, delete_reason) { + Ok(_) => { + logger.info("API", &format!("✅ Soft delete en JSON: {}", app_name)); + } + Err(e) => { + logger.warning("API", &format!("No se pudo hacer soft delete en JSON: {}", e), None); + } + } + + // Intentar 3: Eliminar servicio systemd físicamente (siempre intentar) + let _ = SystemCtl::stop(&service_name); + logger.info("API", &format!("Deteniendo servicio: {}", service_name)); + + let _ = SystemCtl::disable(&service_name); + logger.info("API", &format!("Deshabilitando servicio: {}", service_name)); + + match ServiceGenerator::delete_service_file(&service_name) { + Ok(_) => { + logger.info("API", &format!("✅ Archivo .service eliminado: {}", service_name)); + } + Err(e) => { + logger.warning("API", &format!("No se pudo eliminar .service: {}", e), None); + } + } + + let _ = SystemCtl::daemon_reload(); + logger.info("API", "🔄 daemon-reload ejecutado"); + + Ok(Json(ApiResponse::success(OperationResponse { + app_name: app_name.clone(), + operation: "unregister".to_string(), + success: true, + message: format!("Aplicación '{}' eliminada exitosamente (servicio systemd + soft delete en JSON)", app_name), + }))) } pub async fn start_app_handler(