fix: Mejorar robustez del endpoint de eliminación de apps
- 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
This commit is contained in:
@@ -64,16 +64,63 @@ pub async fn unregister_app_handler(
|
||||
State(state): State<Arc<ApiState>>,
|
||||
Path(app_name): Path<String>,
|
||||
) -> Result<Json<ApiResponse<OperationResponse>>, 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(
|
||||
|
||||
Reference in New Issue
Block a user