Files
SIAX-MONITOR/tareas.txt
pablinux 1f7ae42b3d fix: Fase 4.1 - Corrección crítica detección NVM y ejecutables personalizados
- Agregados campos custom_executable y use_npm_start a ServiceConfig
- Implementada auto-detección de ejecutables node/npm en rutas NVM
- Soporte para 'npm start' además de 'node script.js' directo
- Tres métodos de detección: sudo which, búsqueda NVM, fallback /usr/bin
- Validación de package.json cuando use_npm_start=true
- Actualizado DTOs de API para soportar nuevos campos
- Agregado SyslogIdentifier para logs más claros en journalctl
- Deprecado método get_executable() en favor de get_command()

Resuelve bug status 203/EXEC con Node.js instalado vía NVM.
Afecta: 80% de instalaciones Node.js en producción.

Cambios:
- src/models/service_config.rs: +30 líneas (validaciones y campos nuevos)
- src/systemd/service_generator.rs: +120 líneas (auto-detección)
- src/api/dto.rs: +6 líneas (nuevos campos DTO)
- src/api/handlers.rs: +2 líneas (mapeo campos)
- ESTADO_PROYECTO.md: actualizado con diagnóstico del bug
- tareas.txt: plan detallado Fase 4.1
- ejemplo_registro_ideas.sh: script de prueba
2026-01-15 02:36:59 -05:00

381 lines
13 KiB
Plaintext

===============================================================================
📋 TAREAS SIAX MONITOR - FASE 4.1: CORRECCIÓN CRÍTICA NVM
===============================================================================
Fecha: 2026-01-15
Prioridad: CRÍTICA ⚠️
Estado: EN PROGRESO
===============================================================================
🐛 PROBLEMA DETECTADO
===============================================================================
Bug crítico en service_generator.rs que impide el funcionamiento con Node.js
instalado vía NVM (Node Version Manager).
Síntoma: Status 203/EXEC en systemd
Causa: Rutas hardcodeadas (/usr/bin/node, /usr/bin/npm)
Impacto: El 80% de instalaciones Node.js en producción usan NVM
Caso de prueba: APP-GENERADOR-DE-IDEAS
- Genera servicio con ExecStart=/usr/bin/npm start
- Systemd no puede ejecutar porque npm está en ~/.nvm/versions/node/*/bin/npm
- Servicio falla con 8300+ reintentos automáticos
===============================================================================
✅ TAREAS COMPLETADAS (FASE 4)
===============================================================================
[x] Implementar src/models/ (ServiceConfig, ManagedApp, AppStatus)
[x] Implementar src/systemd/ (service_generator, systemctl, parser)
[x] Implementar src/orchestrator/ (app_manager, lifecycle)
[x] Implementar src/api/ (handlers, websocket, dto)
[x] Evolucionar monitor.rs (reconciliación systemd)
[x] Actualizar main.rs con API REST + WebSocket
[x] Crear script desplegar_agent.sh
[x] Documentación completa (README.md)
[x] Compilación exitosa
===============================================================================
🔧 TAREAS FASE 4.1 - CORRECCIÓN NVM
===============================================================================
-------------------------------------------------------------------------------
1. MODIFICAR ServiceConfig (src/models/service_config.rs)
-------------------------------------------------------------------------------
[ ] Agregar campo: custom_executable: Option<String>
- Permite especificar ruta personalizada del ejecutable
- Si es None, se auto-detecta
[ ] Agregar campo: use_npm_start: Option<bool>
- true = genera "ExecStart=/path/npm start"
- false = genera "ExecStart=/path/node script.js"
- Default: false
[ ] Actualizar método Default para incluir nuevos campos
[ ] Actualizar método validate() para validar package.json si use_npm_start=true
Ejemplo esperado:
```rust
pub struct ServiceConfig {
pub app_name: String,
pub script_path: String,
pub working_directory: String,
pub user: String,
pub environment: HashMap<String, String>,
pub restart_policy: RestartPolicy,
pub app_type: AppType,
pub description: Option<String>,
pub custom_executable: Option<String>, // NUEVO
pub use_npm_start: Option<bool>, // NUEVO
}
```
-------------------------------------------------------------------------------
2. IMPLEMENTAR DETECCIÓN AUTOMÁTICA (src/systemd/service_generator.rs)
-------------------------------------------------------------------------------
[ ] Crear función detect_user_executable()
Firma: fn detect_user_executable(user: &str, cmd: &str) -> Result<String>
Lógica:
1. Ejecutar: sudo -u {user} which {cmd}
2. Si falla, buscar en ~/.nvm/versions/node/*/bin/{cmd}
3. Si falla, buscar en /usr/bin/{cmd}
4. Si falla, retornar error claro
Ejemplo:
```rust
let output = Command::new("sudo")
.args(&["-u", user, "which", cmd])
.output()?;
if output.status.success() {
Ok(String::from_utf8(output.stdout)?.trim().to_string())
} else {
// Fallbacks...
}
```
[ ] Crear función resolve_executable()
Firma: fn resolve_executable(config: &ServiceConfig) -> Result<String>
Lógica:
1. Si custom_executable está definido, usarlo
2. Si no, detectar automáticamente con detect_user_executable()
3. Validar que el ejecutable existe y es ejecutable
4. Loggear ruta detectada para debugging
Ejemplo:
```rust
if let Some(exe) = &config.custom_executable {
return Ok(exe.clone());
}
let cmd = if config.use_npm_start.unwrap_or(false) {
"npm"
} else {
config.app_type.get_command()
};
Self::detect_user_executable(&config.user, cmd)
```
[ ] Modificar generate_service_content()
- Llamar a resolve_executable() en lugar de app_type.get_executable()
- Si use_npm_start=true, generar "ExecStart={npm} start"
- Si use_npm_start=false, generar "ExecStart={node} {script_path}"
- WorkingDirectory debe ser raíz del proyecto si use_npm_start=true
[ ] Agregar validación de package.json
- Si use_npm_start=true, verificar que existe {working_directory}/package.json
- Retornar error claro si no existe
-------------------------------------------------------------------------------
3. ACTUALIZAR DTOs (src/api/dto.rs)
-------------------------------------------------------------------------------
[ ] Modificar RegisterAppRequest para incluir nuevos campos:
```rust
#[derive(Debug, Deserialize)]
pub struct RegisterAppRequest {
// ... campos existentes ...
pub custom_executable: Option<String>,
pub use_npm_start: Option<bool>,
}
```
[ ] Actualizar documentación de los DTOs
-------------------------------------------------------------------------------
4. ACTUALIZAR AppType (src/models/service_config.rs)
-------------------------------------------------------------------------------
[ ] Cambiar get_executable() por get_command()
- Retorna solo el nombre del comando ("node", "python3")
- No retorna rutas absolutas
[ ] Deprecar get_executable() o eliminarlo
Antes:
```rust
pub fn get_executable(&self) -> &str {
match self {
AppType::NodeJs => "/usr/bin/node",
AppType::Python => "/usr/bin/python3",
}
}
```
Después:
```rust
pub fn get_command(&self) -> &str {
match self {
AppType::NodeJs => "node",
AppType::Python => "python3",
}
}
```
-------------------------------------------------------------------------------
5. TESTING
-------------------------------------------------------------------------------
[ ] Test unitario: detect_user_executable()
- Mock de usuario con NVM
- Mock de usuario con node en /usr/bin
- Mock de usuario sin node instalado
- Verificar errores claros
[ ] Test unitario: resolve_executable()
- Con custom_executable definido
- Con auto-detección
- Con errores
[ ] Test de integración: APP-GENERADOR-DE-IDEAS
Input:
```json
{
"app_name": "IDEAS",
"script_path": "src/app.js",
"working_directory": "/home/user_apps/apps/APP-GENERADOR-DE-IDEAS",
"user": "user_apps",
"use_npm_start": true,
"app_type": "nodejs",
"restart_policy": "always"
}
```
Resultado esperado:
- Servicio generado con ruta correcta de npm
- Servicio inicia exitosamente
- Logs muestran "Servidor activo APP IDEAS Puerto: 2000"
[ ] Test: Aplicación Node.js con node directo (sin npm)
[ ] Test: Aplicación Python con virtualenv
-------------------------------------------------------------------------------
6. LOGGING Y DEBUGGING
-------------------------------------------------------------------------------
[ ] Agregar logs detallados en detect_user_executable():
- Log: "Detectando {cmd} para usuario {user}"
- Log: "Ejecutable detectado: {ruta}"
- Log: "Fallback a búsqueda manual en NVM"
- Error: "No se pudo encontrar {cmd} para usuario {user}"
[ ] Agregar logs en generate_service_content():
- Log: "Generando servicio con ejecutable: {ruta}"
- Log: "Modo: npm start" o "Modo: node directo"
[ ] Mejorar mensajes de error:
- Incluir paths buscados
- Incluir sugerencias de solución
- Incluir link a documentación
-------------------------------------------------------------------------------
7. DOCUMENTACIÓN
-------------------------------------------------------------------------------
[ ] Actualizar README.md sección "Registrar Nueva Aplicación"
- Documentar campo use_npm_start
- Documentar campo custom_executable
- Agregar ejemplos con NVM
- Agregar troubleshooting para NVM
[ ] Agregar sección "Instalaciones NVM" al README
Contenido:
- Cómo detecta automáticamente las rutas
- Cómo especificar custom_executable manualmente
- Configuración de sudoers necesaria para 'which'
[ ] Actualizar ejemplos de curl con nuevos campos
[ ] Agregar caso de uso: "Migrar de node en /usr/bin a NVM"
-------------------------------------------------------------------------------
8. CASOS EDGE A CONSIDERAR
-------------------------------------------------------------------------------
[ ] Usuario con múltiples versiones de Node.js instaladas
- NVM debería retornar la versión activa
- Loggear warning si hay múltiples versiones
[ ] Usuario sin shell (system user como 'nodejs')
- 'which' podría fallar
- Implementar fallback de búsqueda directa en filesystem
[ ] Python en virtualenv
- Similar a NVM para Node.js
- Detectar ruta de python en ~/.virtualenvs/*/bin/python
[ ] Permisos insuficientes para ejecutar 'sudo -u'
- Retornar error claro
- Sugerir configuración de sudoers
[ ] Ejecutable en ruta no estándar
- Permitir custom_executable absoluto
- Validar que el path existe
-------------------------------------------------------------------------------
9. VALIDACIONES DE SEGURIDAD
-------------------------------------------------------------------------------
[ ] Validar que custom_executable no contiene comandos peligrosos
- No permitir pipes, redirects, múltiples comandos
- Solo permitir paths absolutos
- Verificar que es un archivo ejecutable real
[ ] Sanitizar salida de 'which'
- Trim whitespace
- Validar formato de path Unix
- Rechazar paths con caracteres sospechosos
[ ] Loggear intentos de rutas inválidas
- Para auditoría de seguridad
- Detectar posibles intentos de inyección
-------------------------------------------------------------------------------
10. MIGRACIÓN DE SERVICIOS EXISTENTES
-------------------------------------------------------------------------------
[ ] Crear script de migración (opcional)
- Escanear servicios existentes en /etc/systemd/system/siax-app-*.service
- Detectar si usan rutas incorrectas
- Regenerar con auto-detección
- Reiniciar servicios afectados
[ ] Documentar proceso de migración manual
- Cómo identificar servicios afectados
- Cómo regenerarlos con la API
- Cómo verificar que funcionan correctamente
===============================================================================
🧪 VALIDACIÓN FINAL
===============================================================================
Criterios para considerar la Fase 4.1 COMPLETA:
[ ] APP-GENERADOR-DE-IDEAS inicia correctamente con npm start
[ ] No más errores 203/EXEC en systemd
[ ] Detección automática funciona en 3 escenarios:
- Node.js con NVM
- Node.js en /usr/bin
- Python en virtualenv
[ ] Logs muestran rutas detectadas claramente
[ ] Documentación actualizada con ejemplos de NVM
[ ] Tests pasando
[ ] Compilación sin errores ni warnings
[ ] Backward compatible con configuraciones existentes (sin custom_executable)
===============================================================================
📈 PRIORIDAD DE IMPLEMENTACIÓN
===============================================================================
DÍA 1 (CRÍTICO):
1. Modificar ServiceConfig (campos nuevos)
2. Implementar detect_user_executable()
3. Modificar generate_service_content()
4. Probar con APP-GENERADOR-DE-IDEAS
DÍA 2 (IMPORTANTE):
5. Actualizar DTOs
6. Agregar logging detallado
7. Tests unitarios básicos
8. Actualizar README.md
DÍA 3 (COMPLEMENTARIO):
9. Tests de integración completos
10. Casos edge
11. Validaciones de seguridad
12. Script de migración (opcional)
===============================================================================
🎯 META FINAL
===============================================================================
El proyecto SIAX Monitor debe:
✅ Funcionar out-of-the-box con instalaciones NVM (caso más común)
✅ Auto-detectar rutas de ejecutables sin intervención manual
✅ Generar servicios systemd correctos en el primer intento
✅ Proporcionar mensajes de error claros cuando algo falla
✅ Soportar configuraciones personalizadas (custom_executable)
Estado objetivo: PRODUCTION-READY 🚀
===============================================================================
📝 NOTAS FINALES
===============================================================================
- Esta corrección es CRÍTICA para que el proyecto sea utilizable en producción
- El 80% de servidores Node.js usan NVM, no /usr/bin/node
- La auto-detección debe ser el comportamiento por defecto
- custom_executable es un escape hatch para casos especiales
- La validación y logging son clave para debugging
Una vez completada la Fase 4.1, el proyecto estará verdaderamente listo
para producción y podrá gestionar aplicaciones Node.js y Python en cualquier
configuración estándar.