hreyes 0ac899f531 fix(install): la actualizacion de Windows decia que funciono y no cambiaba nada
Actualizar un servidor con el agente en una carpeta NO estandar terminaba en
verde y lo dejaba con la version anterior. Todo el camino de Windows
identificaba al agente por NOMBRE, mientras que lo unico que se actualiza se
identifica por RUTA; en cuanto las dos no coincidian, nada fallaba y nada
cambiaba.

- Se alinea la tarea programada con el binario instalado. `Start-ScheduledTask`
  ejecuta la ruta registrada en su accion, no el -Prefix: si difieren, se copiaba
  el binario nuevo en un sitio y se arrancaba el viejo del otro. Ahora se
  reapunta conservando disparador, principal, ajustes y argumentos; si no se
  puede corregir, FALLA — arrancar a sabiendas el binario anterior es peor.
- La confirmacion de arranque mira la RUTA del proceso. Un agente viejo que
  nunca se detuvo satisfacia igual de bien un `Get-Process -Name`. Si la ruta no
  es legible (un proceso de SYSTEM no la expone sin elevacion) se acepta por
  nombre y se avisa, en vez de revertir una actualizacion correcta por falta de
  informacion.
- Corregido Merge-EnvFile con un config\.env de UNA linea: al asignar la salida
  de un `if`, PowerShell desenrolla un array de un elemento a escalar, asi que
  $lines.Count reventaba con Set-StrictMode y la siembra abortaba la instalacion.

Nuevo scripts/emular-actualizacion-windows.ps1: monta un agente falso (un .exe
real que se queda vivo), una instalacion en una carpeta y una tarea apuntando a
otra, corre el instalador y dice si la actualizacion surtio efecto. Sin elevacion
y sin tocar la instalacion real de la maquina. Es lo que destapo los dos
defectos: contra el instalador anterior reproduce el sintoma exacto —codigo de
salida 0 y "El agente esta corriendo con el binario nuevo" sobre un servidor
intacto— y contra este confirma que ya surte efecto, sin tocar la tarea cuando
ya estaba bien.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 10:28:05 -06:00
2026-07-31 07:27:33 -06:00
2026-06-30 16:40:01 -06:00
2026-06-30 11:29:06 -06:00

CloudRestoreAS

Aplicación de Escritorio para Restauración Automática de Bases de Datos SQL Server

CloudRestoreAS es una aplicación Windows de escritorio desarrollada en Python 3.11+ con interfaz gráfica PySide6/Qt que funciona como daemon de usuario para automatizar la restauración de bases de datos SQL Server a partir de respaldos ZIP (incluyendo ZIP multipart).

🎯 Características Principales

  • Vigilancia Automática: Monitorea carpetas por nuevos archivos ZIP con detección de estabilidad
  • ZIP Multipart: Soporte completo para archivos .zip.001, .zip.002, etc.
  • Extracción con 7-Zip: Integración nativa con 7-Zip para descompresión
  • Restauración SQL Server: Conexión directa vía pyodbc con soporte Windows Auth y SQL Auth
  • Motor Concurrente: Workers configurables para extracción y restauración
  • Mapeo de Nodos: Sistema flexible de mapeo nombre_archivo -> base_datos
  • Interfaz Gráfica Completa: Dashboard, gestión de jobs, configuración, logs
  • System Tray: Minimización a bandeja del sistema para operación 24/7
  • Métricas Persistentes: Base de datos SQLite con auditoría completa
  • Logging Rotativo: Logs automáticos con rotación por tamaño
  • Tolerancia a Fallos: Reintentos, timeouts, y manejo de errores robusto
  • Modo Dry Run: Prueba el pipeline sin ejecutar RESTORE real

📋 Requisitos

Sistema Operativo

  • Windows 10/11
  • Windows Server 2019/2022 o superior
  • Linux x86-64 (servidor o escritorio). En servidor headless (sin pantalla) corre automáticamente en modo Qt offscreen. El binario Linux es autocontenido: no requiere instalar Python, 7-Zip, driver ODBC ni librerías Qt en el destino.

Software Requerido

  1. Python 3.11+

  2. 7-Zip

    • Descargar desde: https://www.7-zip.org/
    • Instalar en ubicación estándar (C:\Program Files\7-Zip)
    • La aplicación puede auto-detectar la instalación
  3. ODBC Driver 17 for SQL Server (o superior)

  4. SQL Server (destino de restauraciones)

    • SQL Server 2016 o superior recomendado
    • Permisos necesarios:
      • CREATE DATABASE
      • ALTER DATABASE
      • RESTORE DATABASE
      • Acceso de lectura/escritura en carpetas de datos

🚀 Instalación

Opción 1: Ejecución desde Código Fuente

  1. Clonar o descargar el proyecto

    cd C:\Aduanasoft\CloudRestoreAs
    
  2. Crear entorno virtual (recomendado)

    python -m venv venv
    .\venv\Scripts\Activate.ps1
    
  3. Instalar dependencias

    pip install -r requirements.txt
    
  4. Ejecutar la aplicación

    python runner.py
    

Opción 2: Ejecutable portable (recomendado para producción)

Todo de una vez (desde WSL) — genera Windows + Linux + los paquetes de release:

./build-all.sh                # ambos + dist/release/*.tar.gz y *.zip
./build-all.sh --linux-only   # solo Linux (Docker)
./build-all.sh --windows-only # solo Windows (PowerShell + build.ps1)
./build-all.sh --clean        # rebuild desde cero

Requiere Docker (para Linux) y, para Windows, powershell.exe accesible desde WSL con Python 3.11+ instalado en Windows.

Solo Windows — generar: .\build.ps1dist\CloudRestoreAS.exe Solo Linux — generar: ./build.sh (o packaging/scripts/docker-build-linux.sh para el entorno controlado) → dist/CloudRestoreAS

📦 Referencia completa de compilación, empaquetado, instalación (install.sh/systemd), flags del binario y verificación: BUILD.md.

El build de Linux embebe dentro del binario, además de la app: las libs de sistema de Qt (cluster xcb/X11 + EGL), el driver ODBC 18 con sus dependencias (unixODBC, Kerberos/GSSAPI, OpenSSL) y el 7-Zip (7zz). Por eso el destino no necesita apt install de nada. (El build se hace en un entorno con esas libs; ver packaging/scripts/download-bundled-deps.sh y docker-build-linux.sh.)

Desplegar en cada equipo (sin Python, sin instalador, sin dependencias de sistema):

  1. Copiar solo el ejecutable a una carpeta.
  2. Ejecutarlo (doble clic o ./CloudRestoreAS).
  3. Se crean automáticamente: config/, Entrada/, Procesados/, Fallados/, Temp/.
  4. Editar config/.env (URL, token e instancia del panel).
  5. Reiniciar la aplicación.

Despliegue en servidor Linux (headless / SQL Server sobre Linux):

sudo ./install.sh --service     # servicio systemd 24/7 (offscreen, motor auto-inicio)
# o manual:
QT_QPA_PLATFORM=offscreen ./CloudRestoreAS --start-engine --headless

install.sh no instala ni descarga nada del sistema: solo coloca el binario, hace el bootstrap de config/ y registra el arranque (systemd headless o autostart de escritorio con --desktop). El data_folder del destino viene del PANEL; con SQL Server sobre Linux serán rutas POSIX (p. ej. /var/opt/mssql/data) y el RESTORE las adapta automáticamente.

Ver packaging/LEEME.txt para instrucciones resumidas.

⚙️ Configuración Inicial

1. Primera Ejecución

Al ejecutar la aplicación por primera vez:

  1. Ve al tab Configuración

  2. Configura las siguientes carpetas:

    • Carpeta de Entrada: Donde se monitoreará por nuevos archivos ZIP
    • Carpeta Procesados: Donde se moverán los ZIP exitosos
    • Carpeta Fallados: Donde se moverán los ZIP que fallen
    • Carpeta Extracción: Temporal para extraer archivos (se limpia automáticamente)
    • Carpeta Data SQL: Donde SQL Server almacena los archivos .mdf/.ldf
  3. Configura 7-Zip:

    • Haz clic en "🔍 Detectar" para auto-detectar
    • O selecciona manualmente 7z.exe
  4. Configura SQL Server:

    • Nombre del servidor (ej: localhost, .\SQLEXPRESS, o IP)
    • Tipo de autenticación:
      • Windows Auth: Recomendado (usa credenciales de Windows)
      • SQL Auth: Requiere usuario y contraseña SQL Server
    • Prueba la conexión con "🔌 Probar Conexión"
  5. Guarda la configuración (💾 Guardar Configuración)

2. Configurar Nodos

Los nodos son el mapeo entre nombre de archivo ZIP y base de datos destino.

  1. Ve al tab Nodos
  2. Haz clic en Nuevo Nodo
  3. Configura:
    • Nombre del Nodo: Nombre exacto del archivo ZIP CON EXTENSIÓN (ej: BACKUP_SISTEMA.ZIP)
      • Se compara en MAYÚSCULAS y case-insensitive
    • Base de Datos: Nombre de la base de datos destino en SQL Server (ej: Sistema_DB)
    • Activo: Marca si el nodo está activo
    • Notas: Información opcional

Ejemplo de configuración de nodo:

Nombre del Nodo: BACKUP_VENTAS.ZIP
Base de Datos: Ventas_Prod
Activo: ✓
Notas: Base de datos de ventas - restauración diaria

3. Configuración Avanzada

Concurrencia:

  • Workers de Extracción: Número de extracciones simultáneas (default: 1)
  • Workers de Restore: Número de restauraciones simultáneas (default: 1)
    • ⚠️ Recomendado mantener en 1 para no saturar SQL Server

Estabilidad de Archivos:

  • Verificar Estabilidad: Activa/desactiva verificación antes de procesar
  • Intervalo de Verificación: Tiempo entre checks (default: 5s)
  • Duración Estable: Tiempo que el archivo debe estar sin cambios (default: 10s)
  • Usar Marcador .ready: Si se activa, requiere archivo .ready junto al ZIP

Timeouts:

  • Extracción: Timeout máximo para 7-Zip (default: 30 min)
  • Restauración: Timeout máximo para RESTORE (default: 60 min)

Características:

  • Modo Dry Run: Simula todo sin ejecutar RESTORE real (para pruebas)
  • Escaneo Automático: Auto-escanea la carpeta de entrada
  • Intervalo de Escaneo: Frecuencia de escaneo (default: 30s)

🎮 Uso

Iniciar el Motor

  1. Menú Motor▶️ Iniciar
  2. O presiona el botón de inicio en el Dashboard
  3. La aplicación comenzará a monitorear la carpeta de entrada

Procesamiento Automático

  1. Copia un archivo ZIP a la Carpeta de Entrada
  2. La aplicación detectará el archivo cuando esté estable
  3. Procesamiento automático:
    • Verificar estabilidad del archivo
    • Identificar nodo y base de datos destino
    • Extraer .bak del ZIP (soporta multipart)
    • Obtener estructura lógica del backup (FILELISTONLY)
    • Restaurar base de datos con REPLACE
    • Limpiar archivos temporales
    • Mover ZIP a carpeta Procesados (con subcarpeta por fecha)

Procesamiento Manual

  1. Menú Motor🔍 Escanear Ahora
  2. Fuerza un escaneo inmediato de la carpeta de entrada

Monitoreo

Dashboard:

  • Contadores en tiempo real (Total, En Cola, Ejecutando, Completados, Fallados)
  • Tiempos promedio de ejecución
  • Estado del motor (Corriendo/Pausado/Detenido)
  • Últimos 10 jobs

Jobs:

  • Lista completa de todos los jobs procesados
  • Filtros por estado, nombre, fecha
  • Vista detallada de cada job:
    • Información general
    • Pasos ejecutados con tiempos
    • Errores y mensajes

Logs:

  • Visualización de eventos del sistema
  • Filtros por nivel (DEBUG, INFO, WARNING, ERROR, CRITICAL)
  • Acceso rápido a carpeta de logs en disco

Pausar/Continuar

  • Menú Motor⏸️ Pausar: Detiene el escaneo pero permite terminar jobs en curso
  • Menú Motor▶️ Continuar: Reanuda el monitoreo

Minimizar a Tray

  • Cerrar la ventana la minimiza a la bandeja del sistema
  • Doble clic en el icono del tray para mostrar/ocultar
  • Clic derecho en el icono para acceder al menú:
    • Mostrar/Ocultar
    • Pausar/Continuar
    • Salir

📊 Archivos Multipart

La aplicación soporta automáticamente archivos ZIP multipart:

BACKUP_SISTEMA.ZIP.001
BACKUP_SISTEMA.ZIP.002
BACKUP_SISTEMA.ZIP.003

Comportamiento:

  • Solo coloca el archivo .001 en la carpeta de entrada
  • Los demás archivos (.002, .003, etc.) deben estar en la misma carpeta
  • 7-Zip detectará automáticamente todas las partes
  • Todos los archivos se moverán juntos a Procesados/Fallados

🔐 Seguridad

Contraseñas SQL

Las contraseñas de SQL Server se cifran usando DPAPI (Data Protection API) de Windows:

  • El cifrado está vinculado al usuario y máquina actuales
  • Las contraseñas no son portables entre usuarios/máquinas
  • Si cambias de usuario, debes reconfigurar las credenciales

Permisos Requeridos

En SQL Server:

-- Crear login (si usa SQL Auth)
CREATE LOGIN [CloudRestoreUser] WITH PASSWORD = 'P@ssw0rd';

-- Otorgar permisos
GRANT CREATE DATABASE TO [CloudRestoreUser];
ALTER SERVER ROLE [dbcreator] ADD MEMBER [CloudRestoreUser];

En Windows:

  • Permiso de lectura/escritura en carpetas configuradas
  • Permiso de ejecución de 7-Zip

🗂️ Estructura de Base de Datos

La aplicación usa SQLite local (data/app.db) con las siguientes tablas:

jobs

Registro de todos los jobs procesados.

job_steps

Pasos individuales de cada job con tiempos y códigos de salida.

nodes

Mapeos de nodo a base de datos.

events

Log de eventos del sistema.

config

Configuración persistente de la aplicación.

🐛 Solución de Problemas

El motor no inicia

Síntomas: Al hacer clic en Iniciar, el motor se detiene inmediatamente.

Solución:

  1. Verifica que todas las carpetas estén configuradas y existan
  2. Verifica que 7-Zip esté instalado y la ruta sea correcta
  3. Revisa los logs para errores específicos

No se detectan archivos ZIP

Síntomas: Copias un ZIP a la carpeta de entrada pero no se procesa.

Solución:

  1. Asegúrate de que el motor esté corriendo (no pausado)
  2. Verifica que el archivo sea .zip o .zip.001
  3. Espera el tiempo de estabilidad configurado (default 10s)
  4. Prueba con Escanear Ahora
  5. Revisa si hay errores de permisos en la carpeta

Error "NODE_NOT_MAPPED"

Síntomas: El job falla con "No existe mapeo activo para nodo..."

Solución:

  1. Ve al tab Nodos
  2. Verifica que existe un nodo con el nombre EXACTO del archivo (con extensión)
  3. Ejemplo: Si el archivo es backup.zip, el nodo debe ser BACKUP.ZIP
  4. Verifica que el nodo esté marcado como Activo

Error de conexión SQL Server

Síntomas: "Error conectando a SQL Server..."

Solución:

  1. Verifica que SQL Server esté corriendo
  2. Prueba la conexión en el tab Configuración (🔌 Probar Conexión)
  3. Si usas SQL Auth, verifica usuario y contraseña
  4. Si usas Windows Auth, verifica que el usuario de Windows tenga permisos
  5. Verifica que ODBC Driver 17 esté instalado:
    Get-OdbcDriver | Where-Object {$_.Name -like "*SQL Server*"}
    

Extracción falla con código de salida 2

Síntomas: El step "extract" falla con exit_code=2

Solución:

  1. Verifica que el archivo ZIP no esté corrupto
  2. Para multipart, asegúrate de que TODAS las partes estén presentes
  3. Verifica que haya espacio suficiente en disco para la extracción
  4. Revisa los logs de 7-Zip en el step para más detalles

RESTORE falla

Síntomas: El step "restore" falla

Solución:

  1. Verifica que el usuario tenga permisos CREATE DATABASE y ALTER DATABASE
  2. Verifica que la carpeta Data SQL exista y tenga permisos de escritura
  3. Si la base de datos ya existe, el RESTORE la sobrescribirá (REPLACE)
  4. Revisa el error específico en el detalle del job
  5. Activa Modo Dry Run para ver el SQL generado sin ejecutarlo

📁 Estructura del Proyecto

CloudRestoreAs/
├── app/
│   ├── db/                  # Capa de acceso a datos
│   │   ├── database.py      # Gestor de SQLite
│   │   ├── job_repository.py
│   │   ├── node_repository.py
│   │   └── ...
│   ├── engine/              # Motor de procesamiento
│   │   ├── engine.py        # Motor principal
│   │   ├── file_watcher.py  # Vigilancia de archivos
│   │   └── restore_worker.py
│   ├── extract/             # Extracción con 7-Zip
│   │   └── seven_zip.py
│   ├── sql/                 # Operaciones SQL Server
│   │   └── sql_manager.py
│   ├── ui/                  # Interfaz gráfica
│   │   ├── main_window.py
│   │   ├── dashboard_tab.py
│   │   ├── jobs_tab.py
│   │   ├── nodes_tab.py
│   │   ├── config_tab.py
│   │   └── logs_tab.py
│   ├── utils/               # Utilidades
│   │   ├── logger.py
│   │   └── crypto.py
│   └── constants.py
├── data/                    # Base de datos SQLite
│   └── app.db
├── logs/                    # Archivos de log
│   └── app.log
├── runner.py                # Punto de entrada
├── requirements.txt         # Dependencias
├── build.ps1               # Script de build
└── README.md               # Este archivo

🔧 Desarrollo

Ejecutar en Modo Debug

python runner.py

Los logs se escriben en:

  • Consola (stdout)
  • Archivo logs/app.log (con rotación automática)

Ejecutar Tests

(Opcional: agregar tests con pytest)

pip install pytest
pytest tests/

📝 Notas Importantes

  1. Backups Antes de Restaurar: Aunque la aplicación usa REPLACE, asegúrate de tener backups de las bases de datos existentes.

  2. Carpeta Data SQL: La carpeta configurada debe ser accesible por SQL Server. Generalmente es:

    • SQL Server 2019: C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA
    • SQL Server 2022: C:\Program Files\Microsoft SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA
  3. Nombres de Nodos: Los nombres de nodos son case-insensitive pero deben incluir la extensión completa.

  4. Operación 24/7: La aplicación está diseñada para correr continuamente. Minimízala a tray y déjala corriendo.

  5. Logs Rotativos: Los logs se rotan automáticamente cada 10MB. Se mantienen 10 archivos de respaldo.

FAQ

P: ¿Puedo procesar múltiples archivos simultáneamente?
R: Sí, configura más workers en Configuración → Concurrencia. Sin embargo, recomendamos mantener restore_workers=1 para no saturar SQL Server.

P: ¿Qué pasa si la aplicación se cierra mientras procesa un job?
R: Al reiniciar, los jobs en estado "extracting/restoring" se marcan como "failed_restart". Puedes configurar políticas de reintento (actualmente el código base lo soporta pero no está en la UI).

P: ¿Puedo usar esto para SQL Server en otra máquina?
R: Sí, especifica el nombre o IP del servidor remoto en Configuración → SQL Server. Asegúrate de que:

  • El puerto SQL Server esté abierto (default 1433)
  • Las credenciales tengan permisos remotos
  • La carpeta Data SQL sea accesible remotamente (o usa UNC paths)

P: ¿Soporta bases de datos con múltiples archivos de datos?
R: Sí, la aplicación usa RESTORE FILELISTONLY para detectar todos los archivos lógicos (MDF, LDF, y archivos adicionales). Solo mantiene el archivo principal de datos (.mdf) y de log (.ldf).

P: ¿Puedo ejecutar esto como Windows Service?
R: Sí, con install.ps1 -Service: registra una tarea programada ONSTART que corre como SYSTEM, sin sesión iniciada y sin UI. No se usa NSSM ni ningún envoltorio descargado — el servidor destino no instala ni baja nada, y una tarea programada ya viene en el SO. Requiere PowerShell como Administrador. Ver BUILD.md §6.

📄 Licencia

© 2026 Aduanasoft. Todos los derechos reservados.

🆘 Soporte

Para soporte o reportar problemas:

  • Revisa primero la sección Solución de Problemas
  • Revisa los logs en el tab Logs o en la carpeta logs/
  • Contacta al equipo de desarrollo

CloudRestoreAS v1.0.0 - Restauración Automática de Bases de Datos SQL Server

Description
No description provided
Readme 593 KiB
Languages
Python 93.1%
PowerShell 6.3%
Batchfile 0.6%