Ir al contenido

Copia de seguridad y restauración

Las actualizaciones del esquema de la base de datos son solo hacia adelante: no existe un camino de regreso a una versión anterior. Una copia de seguridad hecha con vision backup es tu única forma de revertir, por lo que forma parte de la rutina de actualización y no es un extra opcional.

Ventana de terminal
sudo vision backup --output /root/

No hay tiempo de inactividad: la base de datos se captura con VACUUM INTO de SQLite, que toma una copia consistente en un instante dado mientras el servicio sigue escribiendo, y la copia ya tiene el checkpoint aplicado: el archivo comprimido nunca contiene archivos auxiliares WAL/SHM, así que la clase de corrupción “se restauró un WAL antiguo sobre una base de datos nueva” no puede ocurrir. Primero se comprueba la integridad de la base de datos de origen; una copia de una base de datos dañada se rechaza en lugar de sobrescribir tu último archivo comprimido válido.

vision-backup-<host>-<timestamp>.tar.gz
└── vision-backup-<host>-<timestamp>/
├── manifest.json what's inside, schema version, encryption key ids
├── vision.db consistent database snapshot
├── config.yaml
├── vision.env secrets — omit with --no-secrets
├── license.txt license serial — omitted with --no-secrets
├── maps/… floor-plan images — omit with --no-maps
└── systemd/vision.service reference only; restore never writes it

Incluido por defecto:

  • vision.env (secretos). La clave de cifrado que protege cada columna cifrada (credenciales de cámaras y de Alta, secretos de almacenamiento y SMTP, claves de firma de webhooks) existe únicamente en este archivo. Un archivo comprimido sin ella no puede descifrar la base de datos a la que acompaña, por eso los secretos se incluyen por defecto; el archivo comprimido se escribe con permisos 0600.
  • license.txt. El número de serie de la licencia, cuando el host tiene uno (Licencias). restore lo vuelve a colocar como vision:vision 0600. Sin él, el host restaurado arranca bloqueado hasta que se active de nuevo.
  • maps/. Los fondos de los planos son los únicos archivos subidos por operadores fuera de la base de datos, y las filas de la base de datos que los referencian viajan en el mismo archivo comprimido: dejar fuera las imágenes haría que una restauración “exitosa” produjera en silencio planos sin fondo.

Excluido, con el motivo registrado en el manifiesto:

  • Clips y capturas de pantalla: se gestionan por retención y se pueden regenerar; incluirlos haría que las copias de seguridad rutinarias pesaran varios gigabytes.
  • Grabaciones HLS: residen en el almacenamiento propio del servidor Alta, nunca en el host de Vision.
  • El binario: su versión se registra en el manifiesto, pero una copia de seguridad es una reversión de datos, no una reversión de código.

Usa --force para reemplazar un archivo comprimido de salida existente. --recover-wal abre primero la base de datos en modo lectura-escritura para recuperar un WAL obsoleto; ejecuta sudo vision doctor y úsalo solo cuando el comando lo recomiende. En instalaciones no predeterminadas, pasa --config PATH o --db PATH.

Ventana de terminal
sudo vision restore /root/vision-backup-<host>-<timestamp>.tar.gz

La secuencia es deliberadamente cuidadosa:

  1. Todo se verifica antes de que cambie nada en el disco: el manifiesto, la suma de verificación de cada archivo y el contenido del archivo comprimido se comprueban antes de cualquier escritura. Trata un archivo comprimido de otra persona como cualquier archivo no confiable.
  2. Comprobación del esquema. Un archivo comprimido de una compilación más nueva se rechaza de plano: actualiza primero el binario. Un archivo comprimido más antiguo se restaura con una advertencia: el servicio lo migrará hacia adelante en el siguiente arranque, lo cual es irreversible.
  3. Comprobación de claves. Si el archivo comprimido no tiene vision.env, los identificadores de clave de cifrado registrados deben coincidir con una clave que tengas actualmente, o la restauración se rechaza (--force-key-mismatch lo anula).
  4. Se rechaza mientras el servicio está en ejecución. Pasa --stop-service para que detenga el servicio por ti: la restauración nunca lo vuelve a iniciar después, de modo que los problemas salgan a la luz antes que el servicio.
  5. Confirmación escrita. Debes escribir restore <this hostname> para continuar: un comando de un runbook pegado en la máquina equivocada falla en lugar de ejecutarse.
  6. Primero se hace una copia de seguridad preventiva del estado actual. Si esa falla, no ocurre nada más.
  7. Se reemplazan los archivos, se eliminan los archivos auxiliares WAL obsoletos y se verifica el esquema de la base de datos restaurada: cualquier fallo en esta etapa revierte todo.

Después, vuelve a poner el servicio en marcha tú mismo:

Ventana de terminal
sudo vision doctor
sudo vision start
sudo vision status

vision doctor te recuerda eliminar el archivo comprimido preventivo pre-restore-* una vez que estés conforme con que la restauración es correcta.

Para un runbook no interactivo, pasa --yes de forma explícita:

Ventana de terminal
sudo vision restore /root/vision-backup.tar.gz --stop-service --yes

Una copia de seguridad que nadie ha restaurado no es una copia de seguridad. Ejecuta esto cada trimestre:

Ventana de terminal
sudo vision restore <latest-archive> --dry-run

--dry-run ejecuta la verificación completa (manifiesto, sumas de verificación, esquema y compatibilidad de claves) e imprime lo que haría sin escribir nada. Demuestra que el archivo comprimido está íntegro y se puede restaurar en la máquina que realmente lo necesitaría.

Restaurar en hardware distinto está soportado: el comando avisa cuando el archivo comprimido proviene de otro host, y como la confirmación escrita siempre nombra el host en el que estás actualmente, una línea de runbook copiada a la máquina equivocada sigue fallando de forma segura. Después de una restauración entre hosts, revisa http.allowed_origins en la configuración restaurada antes de iniciar: puede que todavía nombre al host anterior.

El license.txt del archivo comprimido es el dispositivo del host anterior. Si el host anterior sigue en ejecución, ahora ambos usan una sola licencia: elimina el dispositivo anterior en tu perfil de Cesbo (licencia → Manage device), o activa el nuevo host como reemplazo de aquel (Licencias).

Una línea de cron es suficiente; el comando no necesita coordinación con el servicio en ejecución:

15 3 * * * root /usr/local/bin/vision backup --output /var/backups/vision/ >>/var/log/vision-backup.log 2>&1

Rota tú mismo los archivos comprimidos antiguos, por ejemplo:

Ventana de terminal
find /var/backups/vision -name 'vision-backup-*.tar.gz' -mtime +30 -delete

Cada archivo comprimido contiene tu clave de cifrado por defecto: aplica a tu almacenamiento de copias de seguridad los mismos controles de acceso que aplicas a /etc/vision/vision.env.