feat: Mejorar estructura de monitored_apps.json con metadata completa

- Añadir campos al modelo MonitoredApp:
  * service_name: Nombre del servicio systemd
  * path: WorkingDirectory de la aplicación
  * entry_point: Archivo de entrada (server.js, app.js, etc.)
  * node_bin: Ruta completa al binario de node/python
  * mode: Modo de ejecución (production, development, test)
  * service_file_path: Ruta al archivo .service de systemd
  * registered_at: Timestamp de registro (ISO 8601)

- Actualizar discovery.rs para extraer toda la información:
  * Parsear ExecStart para obtener node_bin y entry_point
  * Extraer NODE_ENV para determinar el modo
  * Guardar ruta completa al archivo .service
  * Usar add_app_full() con información completa

- Integrar ConfigManager en AppManager:
  * Guardar automáticamente en monitored_apps.json al registrar apps
  * Eliminar del JSON al desregistrar apps
  * Extraer metadata desde ServiceConfig (puerto, entry_point, mode, etc.)

- Mantener retrocompatibilidad con JSON antiguo mediante campos deprecated
- Todos los nuevos campos usan #[serde(default)] para evitar errores de deserialización
This commit is contained in:
2026-01-18 03:26:42 -05:00
parent ad9b46bdc5
commit 8822e9e6b5
21 changed files with 3246 additions and 642 deletions

View File

@@ -1,347 +1,51 @@
#!/bin/bash
#######################################
# SIAX Agent - Script de Despliegue
# Instalación automática production-ready
#######################################
# --- CONFIGURACIÓN ---
BINARY_NAME="siax_monitor"
TARGET="x86_64-unknown-linux-gnu"
LOCAL_PATH="target/$TARGET/release/$BINARY_NAME"
set -e # Salir si hay errores
# 1. Preguntar método de transferencia
echo "Selecciona el método de transferencia:"
select METODO in "scp" "rsync"; do
case $METODO in
scp|rsync) break ;;
*) echo "Opción inválida, elige 1 o 2." ;;
esac
done
# Colores para output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# 2. Compilar
echo "📦 Compilando..."
cargo build --release --target $TARGET
if [ $? -ne 0 ]; then echo "❌ Error en compilación"; exit 1; fi
# Variables
INSTALL_DIR="/opt/siax-agent"
SERVICE_USER="siax-agent"
BACKUP_DIR="/tmp/siax-agent-backup-$(date +%s)"
# --- FUNCIÓN DE SUBIDA ---
upload_file() {
local IP=$1
local USER=$2
local DEST=$3
#######################################
# Funciones
#######################################
echo "🚀 Subiendo a $USER@$IP vía $METODO..."
print_header() {
echo -e "${BLUE}"
echo "============================================"
echo " SIAX Agent - Deployment Script"
echo "============================================"
echo -e "${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
check_root() {
if [ "$EUID" -ne 0 ]; then
print_error "Este script debe ejecutarse como root"
echo "Usa: sudo ./desplegar_agent.sh"
exit 1
fi
}
check_dependencies() {
print_info "Verificando dependencias..."
local deps=("systemctl" "cargo" "rustc")
local missing=()
for dep in "${deps[@]}"; do
if ! command -v $dep &> /dev/null; then
missing+=($dep)
fi
done
if [ ${#missing[@]} -ne 0 ]; then
print_error "Faltan dependencias: ${missing[*]}"
echo ""
echo "Instalación de Rust:"
echo " curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
echo ""
echo "Instalación de systemd (debería estar instalado por defecto):"
echo " sudo apt-get install systemd # Debian/Ubuntu"
echo " sudo yum install systemd # RedHat/CentOS"
exit 1
fi
print_success "Todas las dependencias están instaladas"
}
backup_existing() {
if [ -d "$INSTALL_DIR" ]; then
print_warning "Instalación existente detectada"
print_info "Creando backup en: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
cp -r "$INSTALL_DIR" "$BACKUP_DIR/"
print_success "Backup creado"
fi
}
compile_release() {
print_info "Compilando SIAX Agent en modo release..."
if cargo build --release; then
print_success "Compilación exitosa"
if [ "$METODO" = "scp" ]; then
scp "$LOCAL_PATH" "$USER@$IP:$DEST/"
else
print_error "Error en la compilación"
rollback
exit 1
# rsync -avz: a (archivo/permisos), v (visual), z (comprimido)
rsync -avz "$LOCAL_PATH" "$USER@$IP:$DEST/"
fi
}
create_user() {
if id "$SERVICE_USER" &>/dev/null; then
print_info "Usuario $SERVICE_USER ya existe"
if [ $? -eq 0 ]; then
echo "$IP: Completado."
else
print_info "Creando usuario del sistema: $SERVICE_USER"
useradd --system --no-create-home --shell /bin/false "$SERVICE_USER"
print_success "Usuario creado"
echo "$IP: Falló la subida."
fi
}
install_binary() {
print_info "Instalando binario en $INSTALL_DIR..."
# --- LISTA DE SERVIDORES ---
# Formato: upload_file "IP" "USUARIO" "RUTA_DESTINO"
upload_file "192.168.10.145" "root" "/root/app"
upload_file "192.168.10.150" "pablinux" "/home/pablinux/app"
upload_file "192.168.10.160" "user_apps" "/home/user_apps/apps"
mkdir -p "$INSTALL_DIR"
mkdir -p "$INSTALL_DIR/config"
mkdir -p "$INSTALL_DIR/logs"
cp target/release/siax_monitor "$INSTALL_DIR/siax-agent"
chmod +x "$INSTALL_DIR/siax-agent"
# Copiar archivos de configuración si existen
if [ -f "config/monitored_apps.json" ]; then
cp config/monitored_apps.json "$INSTALL_DIR/config/"
fi
# Copiar archivos web
if [ -d "web" ]; then
cp -r web "$INSTALL_DIR/"
fi
# Permisos
chown -R $SERVICE_USER:$SERVICE_USER "$INSTALL_DIR"
print_success "Binario instalado"
}
configure_sudoers() {
print_info "Configurando permisos sudo para systemctl..."
local sudoers_file="/etc/sudoers.d/siax-agent"
cat > "$sudoers_file" << EOF
# SIAX Agent - Permisos para gestionar servicios systemd
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl start *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl stop *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl restart *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl status *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl enable *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl disable *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl daemon-reload
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl is-active *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/systemctl list-unit-files *
$SERVICE_USER ALL=(ALL) NOPASSWD: /bin/journalctl *
EOF
chmod 0440 "$sudoers_file"
# Validar sintaxis
if visudo -c -f "$sudoers_file" &>/dev/null; then
print_success "Configuración de sudoers creada"
else
print_error "Error en configuración de sudoers"
rm -f "$sudoers_file"
exit 1
fi
}
create_systemd_service() {
print_info "Creando servicio systemd para SIAX Agent..."
cat > /etc/systemd/system/siax-agent.service << EOF
[Unit]
Description=SIAX Agent - Process Monitor and Manager
After=network.target
[Service]
Type=simple
User=$SERVICE_USER
WorkingDirectory=$INSTALL_DIR
ExecStart=$INSTALL_DIR/siax-agent
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=$INSTALL_DIR/config $INSTALL_DIR/logs /etc/systemd/system
ProtectHome=true
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable siax-agent.service
print_success "Servicio systemd creado y habilitado"
}
verify_installation() {
print_info "Verificando instalación..."
local errors=0
# Verificar binario
if [ ! -f "$INSTALL_DIR/siax-agent" ]; then
print_error "Binario no encontrado"
((errors++))
fi
# Verificar permisos
if [ ! -r "$INSTALL_DIR/siax-agent" ]; then
print_error "Permisos incorrectos en binario"
((errors++))
fi
# Verificar servicio
if ! systemctl is-enabled siax-agent.service &>/dev/null; then
print_error "Servicio no habilitado"
((errors++))
fi
# Verificar sudoers
if [ ! -f "/etc/sudoers.d/siax-agent" ]; then
print_warning "Configuración de sudoers no encontrada"
echo " El agente podría tener problemas para gestionar servicios"
fi
if [ $errors -eq 0 ]; then
print_success "Verificación exitosa"
return 0
else
print_error "Verificación falló con $errors errores"
return 1
fi
}
start_service() {
print_info "Iniciando SIAX Agent..."
if systemctl start siax-agent.service; then
sleep 2
if systemctl is-active siax-agent.service &>/dev/null; then
print_success "SIAX Agent iniciado correctamente"
return 0
else
print_error "SIAX Agent no pudo iniciarse"
echo ""
echo "Ver logs con: journalctl -u siax-agent.service -n 50"
return 1
fi
else
print_error "Error al iniciar el servicio"
return 1
fi
}
rollback() {
print_warning "Ejecutando rollback..."
systemctl stop siax-agent.service 2>/dev/null || true
systemctl disable siax-agent.service 2>/dev/null || true
if [ -d "$BACKUP_DIR" ]; then
rm -rf "$INSTALL_DIR"
cp -r "$BACKUP_DIR/siax-agent" "$INSTALL_DIR"
systemctl start siax-agent.service 2>/dev/null || true
print_success "Rollback completado"
else
print_warning "No hay backup disponible para rollback"
fi
}
print_summary() {
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN} ✅ SIAX Agent instalado exitosamente${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
echo "📊 Interface Web: http://localhost:8080"
echo "🔌 API REST: http://localhost:8081/api"
echo "📡 WebSocket: ws://localhost:8081/ws/logs/:app_name"
echo ""
echo "Comandos útiles:"
echo " Estado: sudo systemctl status siax-agent"
echo " Logs: sudo journalctl -u siax-agent -f"
echo " Reiniciar: sudo systemctl restart siax-agent"
echo " Detener: sudo systemctl stop siax-agent"
echo ""
echo "Directorio de instalación: $INSTALL_DIR"
echo "Configuración: $INSTALL_DIR/config/monitored_apps.json"
echo ""
}
#######################################
# Main
#######################################
main() {
print_header
check_root
check_dependencies
backup_existing
compile_release
create_user
install_binary
configure_sudoers
create_systemd_service
if verify_installation; then
if start_service; then
print_summary
exit 0
else
print_error "El servicio no pudo iniciarse correctamente"
print_info "Revisa los logs: journalctl -u siax-agent -n 50"
echo ""
echo "¿Deseas hacer rollback? (y/n)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
rollback
fi
exit 1
fi
else
print_error "La verificación falló"
echo ""
echo "¿Deseas hacer rollback? (y/n)"
read -r response
if [[ "$response" =~ ^[Yy]$ ]]; then
rollback
fi
exit 1
fi
}
main
echo "------------------------------------------------"
echo "Done!"