Commit Graph

5 Commits

Author SHA1 Message Date
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
c2afa52d6f fix(install): actualización desatendida en Windows, con reversión
install.sh recibió la maquinaria de actualización segura y install.ps1 nunca
recibió el equivalente. La asimetría se notaba en producción: actualizar desde
el PANEL dejaba el servidor sin agente.

- -UpdateInPlace: actualiza conservando la tarea y la configuración, sin correr
  el bootstrap (una segunda instancia purga el Temp\ de la que está viva).
- No se interrumpe una restauración en curso: sale con 75 (EX_TEMPFAIL), que el
  PANEL traduce a "reintenta luego". Windows no tenía esta guarda y una
  reinstalación a destiempo dejaba el respaldo vetado y la base en SINGLE_USER.
- Respaldo del binario anterior y reversión automática si el nuevo no arranca.
- Rearranque garantizado en TODOS los modos: la detención corría siempre, pero
  solo -Service volvía a arrancar algo.
- Espera de liberación del .exe de 5s a 30s con reintentos de la copia.
- 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.

Y --headless deja de ser un no-op en Windows: _ensure_qt_platform() salía de
inmediato en win32, así que la tarea ONSTART arrancaba como SYSTEM en la sesión 0
con el plugin Qt 'windows' intentando crear una ventana real. En Linux el unit
fija QT_QPA_PLATFORM=offscreen por fuera, y esa asimetría escondió el defecto.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 08:46:12 -06:00
874fe0c46f fix(install): devolver la propiedad del árbol al usuario del servicio
Instalando con sudo, el agente quedaba sin poder leer ni escribir NADA de lo
suyo, y tanto el panel como su sonda lo reportaban como éxito.

El bootstrap ejecuta el binario como root, y ese arranque crea todo el árbol bajo
PREFIX: config/, config/data/app.db, config/logs/, Entrada/, Procesados/,
Fallados/ y Temp/. La siembra escribe config/.env en 0600, también de root. Pero
el unit se registra con User=$SUDO_USER, así que el agente arranca como una
cuenta común que no puede leer su configuración (load_dotenv sin try/except),
ni guardar jobs en su base, ni mover ZIPs entre las carpetas de trabajo.
install.sh no hacía chown en ninguna parte.

Reproducido en un contenedor antes de arreglarlo: .env root:root 600, app.db y
Entrada/ de root, las tres operaciones del agente fallando — y `test -f` de la
sonda del panel dando ok, o sea verde justo en el caso roto.

SERVICE_USER se resuelve ahora al principio (antes se calculaba dentro del case
de --service, después del bootstrap y de la siembra), conservando la misma
cadena de precedencia. El chown va después de ambos pasos, solo cuando el script
corre como root y el servicio no es root, y solo del usuario —no del grupo—;
`chown` no toca los modos, así que el 0600 del .env sobrevive.

Con dos cuidados que no son opcionales:

- Guarda contra un PREFIX de sistema: un `chown -R` sobre / o /opt sería
  catastrófico. Se rechazan las rutas de sistema y las de un solo componente,
  avisando en vez de abortar una instalación ya hecha.
- Si el chown falla se reporta como ERROR con el comando de arreglo, no se traga.
  Es el mismo criterio que el repo ya aplica al icacls de Windows: no se asume
  que un comando de endurecimiento tuvo éxito.

Probado: arreglo, guarda de /opt, usuario inexistente, y sin sudo (no intenta
nada). Windows no necesita el arreglo simétrico y queda documentado por qué: la
tarea corre como SYSTEM con RunLevel Highest y install.ps1 no restringe ninguna
ACL, así que hereda de su carpeta padre y puede leer todo lo del Administrador.
2026-07-30 16:16:28 -06:00
c3f1d70e23 feature/generador-instaladores-linux-windows 2026-07-30 07:34:17 -06:00
854ffa116f Initial commit: CloudRestoreAS v1.0.0 - Aplicación completa de restauración automática SQL Server 2026-01-25 16:53:00 -07:00