Remote-Pulse: verificación del dump antes de publicar y retener¶
Estado acreditado al 20 de octubre, 20:26 CEST¶
| Capa | Evidencia y límite |
|---|---|
| Servicio | CT280, uvicorn y PostgreSQL16 activos en lectura de las 19:55; no prueba funcional completa |
| Dumps nativos PG | Plantillas timer disabled, sin instancias cargadas en el filtro de las 20:13; otros planificadores desconocidos |
| Selección PBS | Configuración de las 20:17: CT280 incluido, habilitada y a las 05:00 hacia pbs; no acredita ejecución |
| Ejecución PVE | Log local consultado a las 20:26 registra finalización de CT280 en el lote de las 05:00; archivo y recuperación no comprobados |
| Rol Ansible | Entrada obsoleta protegida por PR85; no se aplica al servicio vivo |
| Restauración | Pendiente de acreditar; no se inició una nueva prueba |
Defecto reproducido y corrección en fuente¶
La revisión local del20oct encontró que la plantilla copiaba al destino y
borraba archivos antiguos antes de ejecutar pg_restore --list. Una fixture
con verificación fallida reprodujo publicación no validada y pérdida de un
archivo de45 días. Evidencia privada
next-coverage-review-20261020-40s_v7fg/rp-backup-order-proof.json, SHA256
<REDACTED>.
No prueba que ese script estuviera instalado ni que se perdieran datos reales.
PR82, merge
<REDACTED> a las19:39:04 CEST, cambia el orden:
dump privado → verificación de índice → publicación sin sobrescritura → copia
opcional → retención local. Root abre los descriptores; PostgreSQL mantiene
su usuario postgres y usa stdout/stdin. No requiere acceso de postgres a través
del directorio privado de la aplicación. El leaf de backups queda root:root0700;
se conservan padre0750, ubicación, calendario03:00 y días de retención.
Temporales0600, lock local no bloqueante y publicación mediante hardlink exclusivo con fsync de archivo/directorio evitan sobrescribir una generación existente. Los errores conservan archivos antiguos y no disparan reintento o rollback automático. Un error posterior al link puede dejar un destino incierto que requiere inspección, sin tratarlo como commit confirmado.
Nueve fixtures renderizan la plantilla real y ejecutan shell sobre archivos privados con herramientas PostgreSQL/sudo simuladas: fallos dump/list/copy, destinos existentes y symlink, orden de éxito y exclusión de dos procesos. La CI de PR39467714129 y la posterior39467929520 pasan lint y la matriz Linux3.12/3.14 con flock nativo; se reutiliza la matriz existente de fixtures, sin nuevo job operativo.
Alcance operativo¶
Sólo fuente: no se aplicó el rol, ejecutó pg_dump, consultó PostgreSQL, llamó
al NAS, envió healthchecks o lanzó restauraciones. El play conserva never;
Ansible-pull ordinario no despliega este rol manual. Runtime y coherencia con
fuentes se acreditan por separado antes de cualquier aplicación.
pg_restore --list valida lectura del índice, no una restauración completa.
La presencia de un directorio no prueba montaje o salud NAS; se conserva la
política previa de copia local cuando no existe destino. No se añade recorrido
NAS o poda remota. Los límites de I/O bloqueada y diagnóstico físico siguen
pendientes. Fuente y recuperación.
Comprobación dirigida de CT280: 19:46 CEST¶
El20oct 19:46:27 CEST, propietario revalidado por API PVE: CT280 LXC
running en proxmox. Boot del padre 82d105f6… idéntico antes/después. El lector
sólo accedió a metadatos/rutas fijas locales, tras filtrar mountinfo y rechazar
montajes remotos o desconocidos. No listó backups ni abrió rutas NAS.
El script no existe, tampoco /var/lib/rp/backups. Las unidades
rp-pg-backup.service y rp-pg-backup.timer devuelven LoadState=not-found;
no tienen ejecuciones acreditadas. El padre /var/lib/rp observado es
root:root0755, no la declaración rp:rp0750 del rol. Esta divergencia exige
resolver la implementación viva y su persistencia antes de aplicar el rol;
no se instala por asumir que la plantilla describe el servicio actual.
Los valores predeterminados Resultsuccess/ExecMainStatus0 de una unidad not-found no son un backup correcto. Ausencia de este script/timer tampoco demuestra que CT280 carezca de otras copias o PBS. Ningún servicio/DB/timer fue ejecutado, recreado o reconfigurado; no se consultaron datos, entorno, logs o PG. La corrección de PR82 sigue siendo una prevención fuente, sin runtime aplicado.
Evidencia privada rp-backup-runtime-plan-20261020-mylkat9d/projection.json,
SHA256 <REDACTED>.
Lector host SHA256
<REDACTED>;
nueve fixtures locales pasan, sin contar la observación como prueba de copia.
Procedencia seleccionada del servicio vivo: 19:55 CEST¶
Una segunda lectura mínima a las 19:55:05 CEST, con owner/boot revalidados,
observa rp-server.service loaded/active/running, PID517 e invocación
<REDACTED>; inicio18:45:41. WorkingDirectory
/opt/rp/source/server, ejecutable uvicorn y argumento público
rp_server.main:app; EnvironmentFile /etc/rp/server.env, sin leer contenido.
PostgreSQL16-main también está loaded/active/running, PID194, inicio18:45:41.
Estos estados no prueban consultas, ingestión o salud funcional.
El candidato de código identificado por la unidad src/rp_server/config.py
tiene5295 bytes y SHA256
<REDACTED>,
idéntico al archivo de main actual
<REDACTED>.
Su AST declara postgres_url/PostgresDsn/env_file; no tiene los nombres
DATABASE_URL/RP_CONFIG_PATH de la plantilla antigua. El candidato database.py
usa postgres_url. No se importó la app, resolvió sys.path ni leyó entorno:
son archivos candidatos acreditados por la unidad, no una prueba completa de
resolución de imports o de qué base está usando.
La comparación del repositorio actual, commit19oct21:22:53UTC, acredita server/pyproject.toml versión1.0.15 y ausencia de requirements.txt en su raíz. El rol clona main pero espera requirements.txt y genera DATABASE_URL/RP_CONFIG_PATH. Por ello no debe aplicarse completo sin reconciliar su contrato. El checkout local63e0de5 de septiembre sólo se usó como pista, no como main actual.
La documentación propia propone pg_dump03:30/WAL7d con otro nombre de DB/ruta, pero no identifica unidad/timer/script; no acredita ejecuciones. El próximo paso es descubrir metadatos acotados de timers/planificadores de backup y resolver su fuente, no crear una tarea duplicada por inferencia. No se ejecutaron consultas PostgreSQL, backups, importaciones, probes o cambios del servicio.
Lector revisado v2: once fixtures, rechazo de montajes apilados ambiguos y
stdin/stdout no bloqueantes con deadline compartido. Privado
rp-unit-source-plan-20261020-rmfcdn50/projection.json, SHA256
<REDACTED>.
Lector host SHA256
<REDACTED>.
Privacidad del aviso opcional: 20:07 CEST¶
La PR84 se fusiona a las
20:07:52 CEST en <REDACTED>. La URL privada
opcional de Healthchecks pasa por stdin como configuración de curl, mediante
printf builtin y quoting JSON/shell; deja de aparecer en sus argumentos o en
una variable exportada. La validación previa, con no_log, acepta vacío o HTTP(S)
ASCII visible sin espacios/controles para evitar escapes incompatibles.
Conserva redirecciones, límite de diez segundos y fallo no fatal del aviso.
Once fixtures locales pasan: los nueve casos de publicación y dos de privacidad
y validación, con curl simulado y sin HTTP. La
CI de PR39471725115
acredita lint y Linux Python3.12/3.14. El script generado conserva root:root0700,
protección añadida en 3ccb4dc: la URL puede seguir dentro del archivo privado.
No se aplica el rol ni se envía un aviso real. Estas correcciones no acreditan
copias, recuperación o protección activa de CT280.
La CI posterior39472072101 también termina correcta en lint y ambas versiones Linux.
Temporizadores seleccionados: 20:13 CEST¶
Lectura mínima del20oct20:13:39 CEST, CT280 running en proxmox y boot padre
82d105f6… conservado. De13 unit files timer, tres nombres coinciden con el
filtro rp/remote-pulse/postgres/backup/dump: dpkg-db-backup.timer enabled,
pg_basebackup@.timer disabled y pg_dump@.timer disabled. Entre ocho timers
cargados, sólo coincide dpkg-db-backup, active/waiting. Las plantillas PostgreSQL
no acreditan instancias programadas. El timer de dpkg no acredita una copia
de la aplicación o PostgreSQL. Otros nombres/planificadores y PBS quedan fuera
de este filtro; no se afirma ausencia global de backups.
Una tentativa anterior falló al consultar show de los nombres seleccionados; la repetición diagnóstica20:12 conserva phase=timer_show_command/rc1. La lectura válida posterior ejecutó únicamente los dos listados, sin show, logs, contenido de backups, PostgreSQL, NAS o jobs. No se atribuye el fallo a una plantilla sin evidencia adicional. Owner/boot revalidados y stdin/stdout acotados por plazo.
Evidencia privada rp-backup-timer-lists-only-20261020-s12y23jw/observation.json,
SHA256 <REDACTED>.
Lector host SHA256
<REDACTED>:
cinco fixtures y paridad AST con guardas/captura/parsers previamente revisados.
Recibo diagnóstico rp-backup-timer-plan-20261020-gnug8wju/observation-v3.json,
SHA256 <REDACTED>.
Entrada obsoleta detenida antes de mutaciones: 20:15 CEST¶
PR85, merge
<REDACTED> a20:15:43 CEST, detiene la entrada
manual del rol antes de instalar paquetes, modificar PostgreSQL o renderizar
archivos. No altera el servicio vivo. La tarea cubre los tags actuales sin
always: una fixture mostró que always superaba never y rompía ejecuciones
ordinarias. Cinco pruebas con18 invocaciones Ansible locales verifican omisión
ordinaria, selecciones manuales, check y control negativo con escritura ficticia.
Autor y peer pasan; CI39472897855
correcta en lint y ambas versiones Linux. Saltos deliberados de tags/tareas
quedan fuera de este freno, que no es una política de permisos.
La CI posterior39473210492
también termina correcta; publicación39473210745
correcta después del merge.
La matriz y plan de reconciliación describe instalación de paquete/venv, configuración privada, frontend, orden de migraciones, proxy y recuperación. No es una modernización parcial ni acredita copias reales. La cobertura de configuración PBS se revisa por separado.
Selección programada en Proxmox: 20:17 CEST¶
El20oct20:17:21 CEST, consulta exclusiva de configuración /cluster/backup
y propietario actual por /cluster/resources: CT280 running en proxmox,
boot observador 82d105f6… conservado. De siete tareas configuradas, una
selecciona explícitamente280: <REDACTED_UUID>,
enabled=true, horario 05:00, almacenamiento pbs, sin exclusión de280 y
sin restricción de nodo. No hubo selectores ambiguos/pools pendientes en esta
proyección. Esto acredita selección programada, sin demostrar ejecución
reciente, copia correcta, consistencia de PostgreSQL o restauración.
No se consultó storage, backup-info, PBS, datastores, tareas/logs o NAS ni se
inició trabajo. API JSON procesado en RAM y sólo campos operativos seleccionados
persistidos; ocho fixtures locales pasan por autor, root y peer. Lector privado
rp-pve-backup-config-plan-20261020-kowxbias/reader.py, SHA256
<REDACTED>.
Recibo observation.json, SHA256
<REDACTED>.
El siguiente paso es acreditar historial local de ejecución que incluya280,
sin equiparar un job de grupo correcto a una copia individual no identificada.
Finalización individual registrada: lectura 20:26 CEST¶
Consulta única a las 20:26:10 CEST, owner CT280/proxmox running y boot padre
82d105f6… conservado. De cuatro tareas vzdump archivadas recientes, dos eran
de otro guest explícito y no se leyeron sus logs. Se leyeron únicamente dos
logs locales exactos, regulares y estables, tras validar montaje/ancestros sin
seguir enlaces; no se abrió PBS, NAS o ningún archivo de backup.
El lote con epochs 1792465202–1792465238 corresponde a 05:00:02–05:00:38 CEST
del 20 de octubre y termina OK. Su log identifica un bloque de CT280/lxc inequívoco,
con inicio literal 05:00:11 y finalización 05:00:31, sin zona en esos literales.
Resultado reported_success independiente del TASK OK global. Tamaño no
acreditado. Log de 4330 bytes, SHA256
<REDACTED>.
La tarea más reciente del alcance, 05:30:02–05:31:28 CEST, queda target_context_unknown: no se interpreta su éxito global como éxito de CT280 ni se afirma que 05:00 sea su última ejecución absoluta. Tampoco se atribuye el backend de esa ejecución sólo por coincidir con la configuración PBS actual. El registro acredita finalización informada por PVE, no existencia actual, integridad, consistencia PostgreSQL ni restauración del backup.
Recibo privado rp-vzdump-history-plan-20261020-db0i0a69/observation.json, SHA256
<REDACTED>.
Lector SHA256 <REDACTED>;
once fixtures repetidas por root/peer y formatos contrastados con fuente PVE.
Límites: cuatro tareas/48 h, 512 KiB por log/2 MiB total, plazo cooperativo de 10 s.
Sólo proyecciones seleccionadas; UPID/usuarios/mensajes privados no retornados.