Files
CloudRecoveryAS/CHANGELOG.md
hreyes 399b0483d5 docs: la tarea programada tiene que apuntar a lo que se instalo
BUILD.md gana la seccion del fallo silencioso y como reproducirlo con
scripts/emular-actualizacion-windows.ps1.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 10:28:20 -06:00

11 KiB

Changelog

[Sin publicar]

La actualización de Windows decía que funcionó y no cambiaba nada

Actualizar sobre un servidor con el agente en una carpeta no estándar terminaba en verde y dejaba el servidor con la versión anterior. La causa: todo el camino de Windows identificaba al agente por nombre, mientras que lo único que se actualiza se identifica por ruta.

  • install.ps1 alinea la tarea programada con el binario instalado. Start-ScheduledTask ejecuta la ruta registrada en la acción de la tarea, no el -Prefix: si difieren, se copiaba el binario nuevo en un sitio y se arrancaba el viejo del otro. Ahora se reapunta la tarea conservando disparador, principal, ajustes y argumentos; si no se puede corregir, falla.
  • La confirmación de arranque mira la ruta del proceso, no solo su nombre. Un agente viejo que nunca se detuvo satisfacía igual de bien un Get-Process -Name CloudRestoreAS. Si la ruta no es legible —un proceso de SYSTEM no la expone a una cuenta sin elevación— se acepta por nombre y se avisa, en vez de revertir una actualización correcta por falta de información.
  • Nuevo scripts/emular-actualizacion-windows.ps1: reproduce el escenario completo con un agente falso, sin elevación y sin tocar la instalación real de la máquina. Es lo que destapó este defecto y el siguiente.
  • Corregido Merge-EnvFile con un config\.env de una sola línea. Al asignar la salida de un if, PowerShell desenrolla un array de un elemento a escalar, así que $lines.Count reventaba bajo Set-StrictMode y la siembra de credenciales abortaba la instalación.

Instalación y actualización desatendidas en Windows

El instalador de Windows nunca recibió la maquinaria de actualización segura que sí tiene install.sh, y la asimetría se notaba en producción: actualizar desde el PANEL dejaba el servidor sin agente, o fallaba con un error que no correspondía.

  • install.ps1 -UpdateInPlace: actualiza una instalación existente conservando su tarea programada y su configuración, y sin correr el bootstrap (una segunda instancia purgaría el Temp\ de la que está viva). Es el modo que usa el PANEL para actualizar.
  • No se interrumpe una restauración en curso (Temp\ no vacío): sale con 75 (EX_TEMPFAIL), que el PANEL traduce a "reintenta luego". Windows no tenía esta guarda y una reinstalación a destiempo se llevaba por delante el respaldo que se estuviera restaurando, dejándolo vetado y la base en SINGLE_USER.
  • Respaldo y reversión automática: si el binario nuevo no arranca, se vuelve al anterior. El respaldo solo se descarta tras confirmar que la versión nueva corre.
  • Rearranque garantizado en todos los modos. La detención corría siempre, pero solo -Service volvía a arrancar algo: actualizar con desktop o none mataba el agente y se iba sin dejar señal.
  • La espera a que el SO libere el .exe pasa de 5 s a 30 s con reintentos de la copia: con un antivirus escaneando un onefile de ~270 MB, 5 s se quedaban cortos y la copia abortaba.
  • Se distingue "no es administrador" de "es administrador con el token filtrado por UAC", que es lo que recibe una sesión de OpenSSH. Se veían idénticos y el remedio es el opuesto: el segundo no se arregla cambiando de cuenta sino con LocalAccountTokenFilterPolicy.

--headless ahora funciona en Windows

_ensure_qt_platform() salía de inmediato en win32, así que la bandera no hacía nada ahí. La tarea ONSTART corre como SYSTEM en la sesión 0, sin escritorio interactivo, y arrancaba con el plugin Qt windows intentando crear una ventana real. En Linux el mismo modo funcionaba porque el unit de systemd fija QT_QPA_PLATFORM=offscreen por fuera, y esa asimetría escondió el defecto. Ahora --headless fuerza offscreen en todas las plataformas y no se muestra ventana.

Documentación

  • README.md afirmaba que la app no puede correr como servicio de Windows y sugería NSSM, lo que contradecía a install.ps1 desde que existe. Corregido.
  • packaging/LEEME.txt solo documentaba el camino manual para Windows; ahora incluye el instalador, igual que ya hacía para Linux.

[1.1.0] - 2026-07-29

Distribución e instalación automatizada vía Gitea + PANEL

Publicación de versiones

  • Artefactos con versión en el nombre: CloudRestoreAS-<version>-{linux,win}-<arch>.{tar.gz,zip}, más SHA256SUMS y release.json (manifiesto con sha256, tamaño y deps embebidas).
  • packaging/scripts/publish-release.sh: publica en los paquetes genéricos de Gitea (ADUANASOFT/generic/cloudrestoreas/<version>) y verifica el sha256 contra la propia API de Gitea antes de dar la publicación por buena. Soporta --dry-run, --force y --notify-panel.
  • build-all.sh --publish encadena build → empaquetado → publicación. Se niega a publicar si falta una plataforma: los paquetes genéricos son inmutables y corregirlo quemaría el número de versión.

Contrato con el PANEL

  • POST /api/restore/instance-config ahora reporta también platform y arch, para que el PANEL sepa qué artefacto le corresponde a cada servidor.
  • processed_folder ya se envía en ese mismo reporte (antes se calculaba, no se mandaba).

Instaladores

  • Nuevo install.ps1: instalador de despliegue Windows, autocontenido. Registra una tarea programada ONSTART como SYSTEM para el 24/7 headless — sin NSSM ni descargas en el servidor destino. Detiene la instancia en ejecución antes de reemplazar el .exe.
  • El antiguo install.ps1 (preparación del entorno de desarrollo: Python, venv, pip) se movió a scripts/dev-setup.ps1. Se estaba empaquetando por error en el zip del ejecutable autocontenido, que no necesita nada de eso.
  • install.sh e install.ps1 aceptan --panel-env-file / -PanelEnvFile: fusionan las claves CLOUDRESTORE_PANEL_* en config/.env (replace-or-append, idempotente, con lista blanca) y borran el archivo. El token viaja por archivo 0600, nunca por argumentos, para que no quede visible en ps ni en el historial del destino.
  • install.sh detiene el servicio antes de reemplazar el binario y lo vuelve a levantar si estaba activo. (La razón que se dio aquí —que un ELF en ejecución da ETXTBSY— era incorrecta: eso le pasa a cp, no a install, que desvincula el destino antes de crearlo. Ver BUILD.md.)

Versionado

  • app/__init__.py es la fuente única de la versión; el diálogo Acerca de ya no la trae hardcodeada.
  • Flag --version en el binario, y sello config/.version que escribe el bootstrap (el instalador remoto lo lee por SFTP, porque el .exe se compila con console=False).
  • El .exe ya lleva metadatos de versión de Windows (VSVersionInfo).

Correcciones

  • config/7zip y config/odbc se re-despliegan cuando el build trae otras versiones embebidas, comparando un sello con el sha256 de bundled-versions.json. Antes solo se copiaban si la carpeta estaba vacía, así que una actualización con driver ODBC nuevo conservaba el viejo indefinidamente.

[1.0.0] - 2026-01-25

Lanzamiento Inicial

Características Principales

  • Interfaz gráfica completa con PySide6/Qt
  • Motor de procesamiento concurrente con workers configurables
  • Vigilancia automática de carpeta de entrada
  • Soporte para archivos ZIP multipart (.zip.001, .zip.002, etc.)
  • Extracción automática con 7-Zip
  • Restauración automática de bases de datos SQL Server
  • Sistema de mapeo de nodos (archivo → base de datos)
  • Minimización a bandeja del sistema (system tray)
  • Base de datos SQLite para métricas y auditoría
  • Logging rotativo con múltiples niveles
  • Cifrado de contraseñas con DPAPI
  • Soporte Windows Auth y SQL Auth
  • Modo Dry Run para pruebas
  • Detección de estabilidad de archivos
  • Soporte para marcador .ready
  • Timeouts configurables
  • Tolerancia a fallos y manejo de errores

Tabs de la Interfaz

  • Dashboard: Estadísticas en tiempo real
  • Jobs: Gestión y visualización de jobs con detalles
  • Nodos: CRUD de mapeos nodo → base de datos
  • Configuración: Configuración completa de la aplicación
  • Logs: Visualización de eventos y logs

Base de Datos

  • Tabla jobs: Registro completo de jobs
  • Tabla job_steps: Pasos detallados de cada job
  • Tabla nodes: Mapeos de nodos
  • Tabla events: Log de eventos
  • Tabla config: Configuración persistente

Documentación

  • README.md: Documentación completa
  • QUICKSTART.md: Guía rápida de inicio
  • ADVANCED.md: Configuración avanzada
  • SCRIPTS.md: Ejemplos de scripts de automatización

Scripts Incluidos

  • runner.py: Punto de entrada principal
  • install.ps1: Script de instalación automática
  • build.ps1: Script para generar ejecutable con PyInstaller
  • test_installation.py: Script de verificación de instalación

Requisitos del Sistema

  • Windows 10/11 o Windows Server 2019/2022+
  • Python 3.11+
  • 7-Zip
  • ODBC Driver 17 for SQL Server
  • SQL Server 2016+ (destino de restauraciones)

Dependencias

  • PySide6 >= 6.6.0
  • pyodbc >= 5.0.0
  • pywin32 >= 306

Características Futuras Planificadas

v1.1.0 (Próximo Release)

  • Reintentos automáticos configurables desde UI
  • Notificaciones por email
  • Verificación de espacio en disco antes de procesar
  • Soporte para múltiples instancias SQL Server
  • Importación/Exportación de nodos desde CSV
  • Dashboard mejorado con gráficos
  • Filtros avanzados en tabla de jobs

v1.2.0 (Futuro)

  • API REST para integración externa
  • Webhooks para notificaciones
  • Programación de restauraciones (scheduling)
  • Soporte para otros formatos de compresión (RAR, TAR)
  • Modo cluster (múltiples instancias coordinadas)
  • Soporte para Azure SQL Database
  • Backup/Restore de configuración desde UI

v2.0.0 (Largo Plazo)

  • Soporte multiplataforma (Linux)
  • Interfaz web opcional
  • Modo servicio de Windows
  • Soporte para PostgreSQL y MySQL
  • Machine learning para predicción de tiempos
  • Dashboard en tiempo real con WebSockets

Problemas Conocidos

Limitaciones Actuales

  • Solo soporta una configuración SQL Server (no múltiples instancias)
  • Reintentos automáticos no expuestos en UI (requiere edición manual)
  • No hay verificación automática de espacio en disco
  • System tray no muestra notificaciones toast
  • No hay soporte nativo para archivos RAR

Workarounds Documentados

  • Múltiples instancias SQL: Ver ADVANCED.md sección 7
  • Notificaciones: Ver SCRIPTS.md para monitoreo externo
  • Limpieza automática: Ver SCRIPTS.md para scripts de limpieza

Notas de Seguridad

  • Las contraseñas se cifran con DPAPI (vinculadas a usuario/máquina)
  • Los logs pueden contener información sensible (rutas, nombres de DB)
  • Se recomienda ejecutar con cuenta de servicio dedicada
  • Asegurar permisos apropiados en carpetas de trabajo

Agradecimientos

Desarrollado por el equipo de Aduanasoft para automatización de restauraciones de bases de datos SQL Server.


Nota de Versión: Esta es la versión inicial de CloudRestoreAS. Se agradecen comentarios y sugerencias para futuras versiones.