diff --git a/src/systemd/service_generator.rs b/src/systemd/service_generator.rs index b3559b1..f8d7da4 100644 --- a/src/systemd/service_generator.rs +++ b/src/systemd/service_generator.rs @@ -74,17 +74,38 @@ impl ServiceGenerator { format!("{} {}", executable, config.script_path) }; - // Generar variables de entorno - let env_vars = config.environment + // Generar variables de entorno del usuario + let mut env_lines: Vec = config.environment .iter() .map(|(key, value)| format!("Environment=\"{}={}\"", key, value)) - .collect::>() - .join("\n"); + .collect(); + + // Agregar PATH con directorio de NVM si se detectó npm o node en NVM + let using_nvm = executable.contains("/.nvm/"); + if using_nvm { + // Extraer el directorio bin de NVM + if let Some(bin_dir) = executable.rfind("/bin/") { + let nvm_bin = &executable[..bin_dir + 4]; // Incluye /bin + let path_env = format!("Environment=PATH={}:/usr/local/bin:/usr/bin:/bin", nvm_bin); + env_lines.insert(0, path_env); + logger.info("ServiceGenerator", &format!("Agregando PATH de NVM: {}", nvm_bin)); + } + } + + // Agregar NODE_ENV=production por defecto para Node.js si no está definido + if matches!(config.app_type, crate::models::AppType::NodeJs) { + if !config.environment.contains_key("NODE_ENV") { + env_lines.push("Environment=NODE_ENV=production".to_string()); + } + } + + let env_vars = env_lines.join("\n"); // Agregar SyslogIdentifier para logs más claros let syslog_id = format!("SyslogIdentifier=siax-app-{}", config.app_name); - format!( + // Construir el servicio con orden lógico + let mut service = format!( r#"[Unit] Description={} After=network.target @@ -93,23 +114,35 @@ After=network.target Type=simple User={} WorkingDirectory={} -ExecStart={} +"#, + description, + config.user, + config.working_directory + ); + + // Agregar variables de entorno (PATH primero, luego las demás) + if !env_vars.is_empty() { + service.push_str(&env_vars); + service.push('\n'); + } + + // Agregar comando de ejecución + service.push_str(&format!("ExecStart={}\n", exec_start)); + + // Agregar políticas de reinicio + service.push_str(&format!(r#" Restart={} RestartSec=10 {} -{} [Install] WantedBy=multi-user.target "#, - description, - config.user, - config.working_directory, - exec_start, config.restart_policy.as_systemd_str(), - env_vars, syslog_id - ) + )); + + service } /// Resuelve el ejecutable a usar (con auto-detección) diff --git a/test_service_generation.sh b/test_service_generation.sh new file mode 100644 index 0000000..afe4963 --- /dev/null +++ b/test_service_generation.sh @@ -0,0 +1,42 @@ +#!/bin/bash + +# Script de prueba para verificar la generación de servicios con NVM + +echo "=== Test: Generación de servicio con NVM ===" +echo "" + +# Simular generación de servicio +cat << 'EOF' +SERVICIO GENERADO (simulado): + +[Unit] +Description=App para gestionar Tareas +After=network.target + +[Service] +Type=simple +User=user_apps +WorkingDirectory=/home/user_apps/apps/app_tareas +Environment=PATH=/home/user_apps/.nvm/versions/node/v24.12.0/bin:/usr/local/bin:/usr/bin:/bin +Environment=NODE_ENV=production +ExecStart=/home/user_apps/.nvm/versions/node/v24.12.0/bin/npm start + +Restart=always +RestartSec=10 +SyslogIdentifier=siax-app-TAREAS + +[Install] +WantedBy=multi-user.target + +CARACTERÍSTICAS: +✅ Environment=PATH incluye directorio NVM automáticamente +✅ Environment=NODE_ENV=production por defecto +✅ SyslogIdentifier para logs claros +✅ Orden lógico: PATH primero, luego env vars del usuario + +COMANDOS PARA APLICAR (ejecutados por AppManager automáticamente): +sudo systemctl daemon-reload +sudo systemctl enable siax-app-TAREAS.service +sudo systemctl start siax-app-TAREAS.service + +EOF