mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +00:00
docs: review backup and restore documentation in all seven translations
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Crear copias — flujo interactivo de copia | ProxMenux",
|
||||
"description": "El flujo interactivo de copia en ProxMenux. Dos puntos de entrada (menú TUI de Scripts y UI Web del Monitor), tres destinos, dos modos de perfil, un paso común de staging y un diálogo de confirmación. Documenta la matriz de seis opciones, los perfiles Default y Custom, y qué ve el usuario entre seleccionar una copia y ver el archivo aterrizando en el destino.",
|
||||
"description": "El flujo interactivo de copia de seguridad en ProxMenux. Dos puntos de entrada (el menú TUI de Scripts y la interfaz web de Monitor), tres destinos, dos modos de perfil, un paso de preparación temporal y un diálogo de confirmación. Documenta la matriz de seis opciones, los perfiles predeterminado y personalizado, y lo que ve el usuario desde que selecciona una copia hasta que el archivo se guarda en el destino.",
|
||||
"ogTitle": "ProxMenux Backup — crear copias",
|
||||
"ogDescription": "El flujo interactivo de copia con tres destinos, dos perfiles y un paso común de staging.",
|
||||
"twitterTitle": "Crear copias | ProxMenux",
|
||||
@@ -9,12 +9,12 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "Crear copias",
|
||||
"description": "El flujo interactivo de copia: elegir un destino y un perfil, revisar el resumen de confirmación, y ver el archivo aterrizando. Dos puntos de entrada comparten el mismo backend y producen archivos idénticos.",
|
||||
"section": "Backup & Restore"
|
||||
"description": "El flujo interactivo de copia de seguridad: elige un destino y un perfil, revisa el resumen de confirmación y observa cómo se guarda el archivo. Los dos puntos de entrada comparten el mismo backend y producen archivos idénticos.",
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Dos puntos de entrada, funcionalidad idéntica",
|
||||
"body": "El TUI de Scripts y la UI Web del Monitor exponen <strong>exactamente la misma funcionalidad</strong>. Cada copia — manual o programada — pasa por la misma matriz de elección (tres destinos × dos perfiles) e invoca la misma función backend por celda (<code>_bk_pbs</code>, <code>_bk_borg</code> o <code>_bk_local</code>). Los archivos producidos desde uno u otro punto de entrada son indistinguibles. Cuál usar es una cuestión de preferencia: el TUI es amigable por SSH y admite scripting; el Monitor ofrece click-y-elegir y convive con las vistas de notificaciones y de tail del log."
|
||||
"body": "El TUI de Scripts y la interfaz web de Monitor ofrecen <strong>exactamente las mismas funciones</strong>. Cada copia —manual o programada— pasa por la misma matriz de opciones (tres destinos × dos perfiles) y llama a la misma función del backend en cada celda (<code>_bk_pbs</code>, <code>_bk_borg</code> o <code>_bk_local</code>). Los archivos generados desde cualquiera de los dos puntos de entrada son indistinguibles. La elección depende de tus preferencias: el TUI se puede usar por SSH y mediante scripts; Monitor permite trabajar con clics y reúne las vistas de notificaciones y seguimiento del registro."
|
||||
},
|
||||
"entryPoints": {
|
||||
"heading": "Los dos puntos de entrada",
|
||||
@@ -26,14 +26,14 @@
|
||||
},
|
||||
{
|
||||
"entry": "ProxMenux Monitor (UI Web)",
|
||||
"path": "Pestaña Backups → Create backup",
|
||||
"path": "Backups tab → Create backup",
|
||||
"detail": "Flujo en estilo asistente. Las mismas seis opciones presentadas como formulario de dos pasos (destino → perfil). Se invocan las mismas funciones backend por la API Flask."
|
||||
}
|
||||
]
|
||||
},
|
||||
"modes": {
|
||||
"heading": "Copias manuales vs programadas",
|
||||
"body": "Las copias se pueden producir en dos modos: <strong>manuales</strong> (el flujo interactivo que documenta esta página — el usuario elige un destino y un perfil desde un menú y ve el archivo aterrizando) o <strong>programadas</strong> (un trabajo desatendido que se ejecuta en un timer estilo cron y aplica la retención configurada en el trabajo). Ambos modos soportan los mismos tres destinos y los mismos dos perfiles, y ambos están disponibles desde los dos puntos de entrada — el menú TUI de Scripts y la pestaña Backups del Monitor. Los trabajos programados usan las mismas funciones backend que el flujo manual a través de <code>run_scheduled_backup.sh</code>; los archivos producidos son indistinguibles.",
|
||||
"body": "Las copias se pueden producir en dos modos: <strong>manuales</strong> (el flujo interactivo que documenta esta página — el usuario elige un destino y un perfil desde un menú y ve cómo se guarda el archivo) o <strong>programadas</strong> (un trabajo desatendido que se ejecuta en un timer estilo cron y aplica la retención configurada en el trabajo). Ambos modos soportan los mismos tres destinos y los mismos dos perfiles, y ambos están disponibles desde los dos puntos de entrada — el menú TUI de Scripts y la pestaña Backups del Monitor. Los trabajos programados usan las mismas funciones backend que el flujo manual a través de <code>run_scheduled_backup.sh</code>; los archivos producidos son indistinguibles.",
|
||||
"seeAlso": "La página de trabajos programados cubre el flujo completo, incluyendo cómo crear un trabajo, adjuntarlo a un timer vzdump de PVE existente, y configurar los valores de retención.",
|
||||
"monitorAlt": "Pestaña Backups del Monitor de ProxMenux mostrando el diálogo New scheduled backup con los campos de destino, perfil, horario y retención.",
|
||||
"monitorCaption": "Copia programada — Monitor de ProxMenux. El mismo diálogo estilo asistente que crea una copia manual lleva los campos de horario y retención al final para la ruta desatendida."
|
||||
@@ -45,46 +45,46 @@
|
||||
{
|
||||
"combo": "1",
|
||||
"destination": "PBS",
|
||||
"profile": "Default",
|
||||
"profile": "Por defecto",
|
||||
"action": "Sube el perfil por defecto más los extras persistentes a un repositorio PBS configurado."
|
||||
},
|
||||
{
|
||||
"combo": "2",
|
||||
"destination": "Borg",
|
||||
"profile": "Default",
|
||||
"profile": "Por defecto",
|
||||
"action": "Crea un archivo con el perfil por defecto más los extras persistentes en el repositorio Borg seleccionado."
|
||||
},
|
||||
{
|
||||
"combo": "3",
|
||||
"destination": "Local",
|
||||
"profile": "Default",
|
||||
"profile": "Por defecto",
|
||||
"action": "Escribe un archivo <code>.tar.zst</code> con el perfil por defecto más los extras persistentes en el destino local configurado."
|
||||
},
|
||||
{
|
||||
"combo": "4",
|
||||
"destination": "PBS",
|
||||
"profile": "Custom",
|
||||
"action": "Abre el path picker antes de la subida a PBS; el usuario marca rutas y puede añadir nuevas."
|
||||
"profile": "Personalizado",
|
||||
"action": "Abre el selector de rutas antes de la subida a PBS; el usuario marca las rutas y puede añadir otras nuevas."
|
||||
},
|
||||
{
|
||||
"combo": "5",
|
||||
"destination": "Borg",
|
||||
"profile": "Custom",
|
||||
"action": "Abre el path picker antes de crear el archivo Borg."
|
||||
"profile": "Personalizado",
|
||||
"action": "Abre el selector de rutas antes de crear el archivo Borg."
|
||||
},
|
||||
{
|
||||
"combo": "6",
|
||||
"destination": "Local",
|
||||
"profile": "Custom",
|
||||
"action": "Abre el path picker antes de escribir el <code>.tar.zst</code> local."
|
||||
"profile": "Personalizado",
|
||||
"action": "Abre el selector de rutas antes de escribir el <code>.tar.zst</code> local."
|
||||
}
|
||||
]
|
||||
},
|
||||
"profiles": {
|
||||
"heading": "Perfil Default vs Custom",
|
||||
"defaultTitle": "Perfil Default",
|
||||
"heading": "Perfil predeterminado y personalizado",
|
||||
"defaultTitle": "Perfil predeterminado",
|
||||
"defaultBody": "El perfil por defecto es la lista curada de <code>hb_default_profile_paths</code> (documentada en <em>Cómo funciona</em> bajo <em>Categorías de rutas</em>) más cada entrada del fichero de extras persistentes <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code>. El usuario confirma el destino y las opciones de cifrado y la copia continúa sin más selección de rutas.",
|
||||
"customTitle": "Perfil Custom",
|
||||
"customTitle": "Perfil personalizado",
|
||||
"customBody": "El perfil Custom abre un checklist mostrando cada ruta del perfil por defecto (sin marcar) y cada extra persistente (premarcado, prefijado con <code>[+]</code>). El usuario marca el conjunto para esa ejecución y puede pulsar <em>Add custom path</em> para añadir una nueva ruta absoluta. Cualquier ruta añadida en línea se persiste en <code>backup-extra-paths.txt</code> para que futuras copias la recojan automáticamente sin volver a añadirla. Quitar la marca a un extra persistente lo desmarca para esa ejecución pero no lo elimina del fichero — la eliminación es una acción <em>Manage custom paths</em> separada, fuera del flujo de copia.",
|
||||
"customPickerAlt": "Checklist del perfil Custom mostrando las rutas del perfil por defecto (sin marcar) y los extras persistentes (premarcados con prefijo [+]), más botones para añadir una ruta nueva o confirmar la selección.",
|
||||
"customPickerCaption": "Perfil Custom — el path picker. Las rutas del perfil por defecto aparecen sin marcar; los extras persistentes aparecen premarcados con prefijo [+]. El usuario marca el conjunto para esa ejecución.",
|
||||
@@ -118,7 +118,7 @@
|
||||
{
|
||||
"step": "5",
|
||||
"name": "Notificación (start)",
|
||||
"detail": "Se dispara <code>hb_notify_lifecycle \"start\"</code>. Si las notificaciones están configuradas en el Monitor, se emite un evento usuario-facing <em>Host backup started</em>. Silencioso si no hay canales configurados."
|
||||
"detail": "Se ejecuta <code>hb_notify_lifecycle \"start\"</code>. Si las notificaciones están configuradas en Monitor, se emite un evento <em>Copia de seguridad del host iniciada</em> para el usuario. No se envía nada si no hay canales configurados."
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -157,7 +157,7 @@
|
||||
"<strong>Filesystems runtime del kernel y sistema</strong> — <code>/proc</code>, <code>/sys</code>, <code>/dev</code> y <code>/run</code> son pseudo-filesystems que produce el kernel y udev; no se persisten en ningún sitio.",
|
||||
"<strong>Binarios de paquetes bajo <code>/usr/bin</code>, <code>/usr/lib</code>, <code>/lib</code>, <code>/sbin</code></strong> — los reinstala el APT del destino a partir de <code>packages.manual.list</code>.",
|
||||
"<strong><code>/var/log/</code>, <code>/var/tmp/</code>, <code>/var/cache/</code></strong> — estado runtime por host, no se restaura.",
|
||||
"<strong><code>/home/USUARIO</code></strong> — no está en el perfil por defecto. Añadirlo como ruta custom cuando un sistema tenga directorios home de usuario que deban sobrevivir a una restauración."
|
||||
"<strong><code>/home/USER</code></strong> — no está en el perfil por defecto. Añadirlo como ruta custom cuando un sistema tenga directorios home de usuario que deban sobrevivir a una restauración."
|
||||
],
|
||||
"customPathsTitle": "Cómo se tratan las rutas custom",
|
||||
"customPathsBody": "Una ruta custom añadida en línea en modo Custom o persistida en <code>backup-extra-paths.txt</code> pasa por el mismo pipeline de <code>rsync</code> que las rutas del perfil por defecto. Se aplican las exclusiones globales. Si la ruta custom está bajo <code>/root/</code> o <code>/usr/local/share/proxmenux/</code>, siguen aplicando las exclusiones específicas de arriba. Cada ruta archivada — default o custom — queda registrada en <code>metadata/paths_archived.txt</code>. Las rutas que no existen en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
|
||||
@@ -165,7 +165,7 @@
|
||||
"archiveStructure": {
|
||||
"heading": "Estructura del archivo",
|
||||
"intro": "El directorio de staging que produce cada backend sigue el mismo layout con independencia del destino. El tarball, el <code>.pxar</code> de PBS o el archivo Borg almacenan este árbol verbatim.",
|
||||
"tree": "backup-[timestamp]/\n├── manifest.json # estado estructurado del host (kernel_params, hardware, storage, guests, components, source_host)\n├── metadata/\n│ ├── packages.manual.list # salida de apt-mark showmanual\n│ ├── run_info.env # hostname, timestamp, versión del kernel, método pmxcfs\n│ ├── paths_archived.txt # lista exacta de rutas que llegaron a rootfs/\n│ └── missing_paths.txt # rutas del perfil ausentes en el origen\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/systemd/network, /etc/ssh, /etc/apt, ...\n ├── root/ # /root sin subpaths volátiles\n ├── usr/local/ # /usr/local/bin, /usr/local/sbin, /usr/local/share/proxmenux (sólo estado)\n └── var/ # /var/lib/pve-cluster (config.db vía sqlite3 .backup), /var/spool/cron/crontabs"
|
||||
"tree": "backup-[timestamp]/\n├── manifest.json # structured host state (kernel_params, hardware, storage, guests, components, source_host)\n├── metadata/\n│ ├── packages.manual.list # output of apt-mark showmanual\n│ ├── run_info.env # hostname, timestamp, kernel version, pmxcfs method\n│ ├── paths_archived.txt # exact list of paths that reached rootfs/\n│ └── missing_paths.txt # paths from the profile absent on source\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/systemd/network, /etc/ssh, /etc/apt, ...\n ├── root/ # /root without volatile subpaths\n ├── usr/local/ # /usr/local/bin, /usr/local/sbin, /usr/local/share/proxmenux (state only)\n └── var/ # /var/lib/pve-cluster (config.db via sqlite3 .backup), /var/spool/cron/crontabs"
|
||||
},
|
||||
"confirmation": {
|
||||
"heading": "Resumen de confirmación",
|
||||
@@ -184,7 +184,7 @@
|
||||
"detail": "<code>hb_write_archive_sidecar</code> deposita un <code>*.proxmenux.json</code> junto al archivo local para que el Monitor lo identifique como copia de host de ProxMenux incluso tras movimientos o renombrados."
|
||||
},
|
||||
{
|
||||
"topic": "Notificación (complete/fail)",
|
||||
"topic": "Notificación (éxito o fallo)",
|
||||
"detail": "Se dispara <code>hb_notify_lifecycle \"complete\"</code> o <code>\"fail\"</code> con duración, tamaño del archivo y — en fallos — la última línea del log que parezca un error."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,19 +10,31 @@
|
||||
"header": {
|
||||
"title": "Restauración cross-kernel",
|
||||
"description": "Cómo maneja ProxMenux una restauración cuando el kernel del host de destino es distinto al kernel que había en el momento de la copia — especialmente cuando el destino ejecuta un kernel más reciente. Documenta cómo se detecta la diferencia, cómo se filtran las rutas críticas del arranque que podrían romper el destino, y cómo se reaplica la configuración propia del usuario sin copiar verbatim los ficheros ligados al kernel.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Cada salto de kernel se maneja de forma distinta",
|
||||
"body": "Cuando la restauración detecta que la copia y el destino tienen versiones mayores distintas de kernel, el flujo se ramifica en función de la dirección del salto — si la copia es más antigua o más reciente que el destino — porque los dos casos tienen modos de fallo opuestos. Las copias más recientes que el destino se restauran limpiamente tal cual (verificado empíricamente en múltiples pruebas de banco). Las copias más antiguas que el destino necesitan un filtro para evitar romper el arranque del destino con configuración escrita para un kernel que desde entonces ha cambiado."
|
||||
"body": "El kernel de un host Proxmox se identifica mediante una versión como <code>6.17.13-2-pve</code>. Los dos primeros números (<strong>6.17</strong> en este ejemplo) definen la versión principal: cuando cambian, algunos archivos de configuración del kernel anterior podrían no ser válidos para el nuevo. Si la restauración detecta versiones principales distintas en la copia y en el destino, el proceso toma un camino u otro según la dirección del salto: si el kernel de la copia es anterior o posterior al del destino. Los dos casos presentan riesgos opuestos. Las copias con un kernel más reciente que el del destino se restauran tal cual, sin problemas según las pruebas realizadas con varios saltos de kernel. Las copias con un kernel anterior al del destino necesitan un filtro para evitar que una configuración del kernel antiguo impida arrancar el sistema de destino."
|
||||
},
|
||||
"directionCheck": {
|
||||
"heading": "La comprobación de dirección",
|
||||
"intro": "Durante la comprobación de compatibilidad, <code>hb_compat_check</code> compara el kernel registrado en el manifiesto de la copia contra el kernel actual del destino (<code>uname -r</code>) y clasifica la restauración en uno de tres casos, guardado en la variable interna <code>HB_COMPAT_KERNEL_DIRECTION</code>:",
|
||||
"rows": [
|
||||
{ "direction": "same", "condition": "La versión mayor del kernel coincide entre la copia y el destino.", "behavior": "El flujo de restauración completo corre sin cambios. Sin filtro adicional, sin hidratación, sin aviso especial en la interfaz." },
|
||||
{ "direction": "bk_newer", "condition": "El kernel de la copia es más RECIENTE que el del destino (por ejemplo: la copia se hizo con kernel 7.0 y el destino corre kernel 6.17).", "behavior": "El flujo de restauración completo corre sin cambios, exactamente igual que en <code>same</code>. No se aplica ningún filtro. Verificado empíricamente: los controladores se reinstalan contra el kernel del destino, la configuración IOMMU se aplica limpia, las VMs con passthrough GPU arrancan sin problemas." },
|
||||
{ "direction": "bk_older", "condition": "El kernel de la copia es más ANTIGUO que el del destino (por ejemplo: la copia se hizo con kernel 6.17 y el destino corre kernel 7.0).", "behavior": "Se activan el filtro de subconjunto seguro y la hidratación de cuatro fases descritos más abajo. La restauración procede — el destino reproduce el origen, pero los ficheros críticos del arranque no se copian verbatim." }
|
||||
{
|
||||
"direction": "same",
|
||||
"condition": "La versión mayor del kernel coincide entre la copia y el destino.",
|
||||
"behavior": "El flujo de restauración completo corre sin cambios. Sin filtro adicional, sin hidratación, sin aviso especial en la interfaz."
|
||||
},
|
||||
{
|
||||
"direction": "bk_newer",
|
||||
"condition": "El kernel de la copia es más RECIENTE que el del destino (por ejemplo: la copia se hizo con kernel 7.0 y el destino corre kernel 6.17).",
|
||||
"behavior": "El flujo de restauración completo corre sin cambios, exactamente igual que en <code>same</code>. No se aplica ningún filtro. Verificado empíricamente: los controladores se reinstalan contra el kernel del destino, la configuración IOMMU se aplica limpia, las VMs con passthrough GPU arrancan sin problemas."
|
||||
},
|
||||
{
|
||||
"direction": "bk_older",
|
||||
"condition": "El kernel de la copia es más ANTIGUO que el del destino (por ejemplo: la copia se hizo con kernel 6.17 y el destino corre kernel 7.0).",
|
||||
"behavior": "Se activan el filtro de subconjunto seguro y la hidratación de cuatro fases descritos más abajo. La restauración procede — el destino reproduce el origen, pero los ficheros críticos del arranque no se copian verbatim."
|
||||
}
|
||||
]
|
||||
},
|
||||
"whyBkNewerIsSafe": {
|
||||
@@ -31,25 +43,60 @@
|
||||
},
|
||||
"safeSubsetFilter": {
|
||||
"heading": "El filtro de subconjunto seguro (sólo cuando el kernel del destino es más reciente)",
|
||||
"intro": "Cuando el kernel del destino es más reciente que el de la copia, la comprobación de compatibilidad añade 16 rutas críticas del arranque de <code>hb_unsafe_paths_cross_version</code> a <code>RS_SKIP_PATHS</code>. Estas rutas se excluyen de la restauración porque escribir una versión suya de un kernel más antiguo sobre un destino que corre uno más reciente ha causado kernel panics en pruebas de banco. Las rutas cubren cuatro categorías:",
|
||||
"intro": "Cuando el kernel del destino es más reciente que el de la copia, la comprobación de compatibilidad añade 16 rutas críticas del arranque de <code>hb_unsafe_paths_cross_version</code> a <code>RS_SKIP_PATHS</code>. Estas rutas se excluyen de la restauración porque escribir una versión suya de un kernel más antiguo sobre un destino que corre uno más reciente ha causado kernel panics en pruebas de banco. Las rutas cubren cinco categorías:",
|
||||
"categoryRows": [
|
||||
{ "category": "Bootloader", "paths": "<code>/etc/default/grub</code>, <code>/etc/kernel</code>", "reason": "Defaults de GRUB atados al orden previo de kernels, y estado de proxmox-boot-tool (cmdline, UUIDs de ESP, hooks) que referencia rutas e identificadores de la instalación más antigua." },
|
||||
{ "category": "Módulos del kernel y artefactos de arranque", "paths": "<code>/etc/modules-load.d</code>, <code>/etc/modprobe.d</code>, <code>/etc/initramfs-tools</code>", "reason": "Listas de autocarga que pueden referenciar módulos renombrados entre majors del kernel, opciones de módulo que pueden no aplicar, hooks de initramfs escritos para el kernel más antiguo." },
|
||||
{ "category": "Stack de almacenamiento e identidad de filesystem", "paths": "<code>/etc/fstab</code>, <code>/etc/multipath</code>, <code>/etc/iscsi</code>, <code>/etc/udev/rules.d</code>, <code>/etc/zfs</code>", "reason": "UUIDs que pueden no existir en esta instalación, drivers de multipath que cambian entre kernels, parámetros iSCSI que evolucionan, reglas udev que pueden atarse a subsistemas inexistentes, estado ZFS (<code>zpool.cache</code> + <code>hostid</code>) que puede bloquear el pool como si no perteneciera al host." },
|
||||
{ "category": "Fuentes APT", "paths": "<code>/etc/apt</code>", "reason": "Las suites de fuentes APT pueden disparar un downgrade de paquetes críticos en la próxima actualización." },
|
||||
{ "category": "systemd", "paths": "<code>/etc/systemd/system</code>, <code>/etc/systemd/journald.conf</code>, <code>/etc/systemd/logind.conf</code>, <code>/etc/systemd/system.conf</code>, <code>/etc/systemd/user.conf</code>", "reason": "Overrides de unit y .wants ligados al major de systemd más antiguo; claves de configuración que pueden no parsearse en un systemd más reciente." }
|
||||
{
|
||||
"category": "Cargador de arranque",
|
||||
"paths": "<code>/etc/default/grub</code>, <code>/etc/kernel</code>",
|
||||
"reason": "Defaults de GRUB atados al orden previo de kernels, y estado de proxmox-boot-tool (cmdline, UUIDs de ESP, hooks) que referencia rutas e identificadores de la instalación más antigua."
|
||||
},
|
||||
{
|
||||
"category": "Módulos del kernel y artefactos de arranque",
|
||||
"paths": "<code>/etc/modules-load.d</code>, <code>/etc/modprobe.d</code>, <code>/etc/initramfs-tools</code>",
|
||||
"reason": "Listas de autocarga que pueden referenciar módulos renombrados entre majors del kernel, opciones de módulo que pueden no aplicar, hooks de initramfs escritos para el kernel más antiguo."
|
||||
},
|
||||
{
|
||||
"category": "Stack de almacenamiento e identidad de filesystem",
|
||||
"paths": "<code>/etc/fstab</code>, <code>/etc/multipath</code>, <code>/etc/iscsi</code>, <code>/etc/udev/rules.d</code>, <code>/etc/zfs</code>",
|
||||
"reason": "UUIDs que pueden no existir en esta instalación, drivers de multipath que cambian entre kernels, parámetros iSCSI que evolucionan, reglas udev que pueden atarse a subsistemas inexistentes, estado ZFS (<code>zpool.cache</code> + <code>hostid</code>) que puede bloquear el pool como si no perteneciera al host."
|
||||
},
|
||||
{
|
||||
"category": "Fuentes APT",
|
||||
"paths": "<code>/etc/apt</code>",
|
||||
"reason": "Las suites de fuentes APT pueden disparar un downgrade de paquetes críticos en la próxima actualización."
|
||||
},
|
||||
{
|
||||
"category": "systemd",
|
||||
"paths": "<code>/etc/systemd/system</code>, <code>/etc/systemd/journald.conf</code>, <code>/etc/systemd/logind.conf</code>, <code>/etc/systemd/system.conf</code>, <code>/etc/systemd/user.conf</code>",
|
||||
"reason": "Overrides de unit y .wants ligados al major de systemd más antiguo; claves de configuración que pueden no parsearse en un systemd más reciente."
|
||||
}
|
||||
],
|
||||
"outroBody": "El filtro corre ANTES del diálogo de confirmación para que el usuario vea la lista exacta de rutas que se saltarán, categorizadas por motivo. La restauración procede igualmente — todo lo demás (VMs, LXCs, red, /etc/pve, usuarios, cron, estado de ProxMenux, paquetes, drivers, /root) se restaura con normalidad."
|
||||
"outroBody": "El filtro corre ANTES del diálogo de confirmación para que el usuario vea la lista exacta de rutas que se saltarán, categorizadas por motivo. La restauración procede igualmente — todo lo demás (configuración de VM/LXC, red, /etc/pve, usuarios, cron, estado de ProxMenux, paquetes, drivers, /root) se restaura con normalidad."
|
||||
},
|
||||
"hydration": {
|
||||
"heading": "Hidratación independiente del kernel",
|
||||
"intro": "El filtro de subconjunto seguro por sí solo dejaría al destino sin la configuración que el usuario había puesto dentro de esos ficheros críticos del arranque: cmdline IOMMU para passthrough GPU, IDs de dispositivo VFIO, <code>GRUB_TIMEOUT</code> custom, blacklists de nvidia. La pasada de hidratación reaplica esas piezas de forma independiente de la versión del kernel. Corren cuatro fases cuando el kernel del destino es más reciente que el de la copia, cada una aditiva (nunca sobrescribe un valor que el destino ya lleva) e idempotente (correr dos veces es un no-op).",
|
||||
"intro": "El filtro omite archivos críticos del arranque; la hidratación reaplica ajustes seleccionados: cmdline IOMMU, IDs VFIO, <code>GRUB_TIMEOUT</code> personalizado y listas de bloqueo nvidia. Se ejecuta con un kernel destino más reciente. La fusión de cmdline conserva las claves del destino y añade módulos que faltan. Los valores GRUB y archivos permitidos pueden reemplazar contenido distinto del destino. Repetir la misma entrada es idempotente.",
|
||||
"phaseRows": [
|
||||
{ "phase": "1a — Ruta GRUB", "detail": "Para hosts que usan GRUB (instalaciones ext4/lvm). <code>_rs_hyd_grub</code> mergea cada token de <code>manifest.kernel_params.cmdline_extra</code> de la copia en el <code>GRUB_CMDLINE_LINUX_DEFAULT</code> vivo del destino, saltando los tokens cuya clave el destino ya lleva. Después mergea claves whitelisted <code>GRUB_*</code> (<code>GRUB_TIMEOUT</code>, <code>GRUB_TIMEOUT_STYLE</code>, <code>GRUB_DEFAULT</code>, <code>GRUB_TERMINAL</code>, <code>GRUB_DISABLE_OS_PROBER</code>, <code>GRUB_SERIAL_COMMAND</code>, <code>GRUB_GFXMODE</code>, <code>GRUB_GFXPAYLOAD_LINUX</code>) del <code>/etc/default/grub</code> de la copia si difieren de las del destino." },
|
||||
{ "phase": "1b — Ruta systemd-boot / ZFS", "detail": "Para hosts que usan systemd-boot (típicamente ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> mergea los tokens del usuario de <code>cmdline_extra</code> en el <code>/etc/kernel/cmdline</code> del destino, manteniendo intacto el boilerplate propio del destino: <code>root=</code>, <code>boot=</code> y <code>rootflags=</code>." },
|
||||
{ "phase": "2 — Merge en /etc/modules", "detail": "<code>_rs_hyd_modules</code> añade los módulos de <code>manifest.kernel_params.modules_loaded_at_boot</code> que estén en la whitelist (<code>vfio</code>, <code>vfio_pci</code>, <code>vfio_iommu_type1</code>, <code>vfio_virqfd</code>, <code>kvm</code>, <code>kvm_intel</code>, <code>kvm_amd</code>, <code>nvidia</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia_uvm</code>, <code>i915</code>, <code>xe</code>) Y que aún no estén presentes en <code>/etc/modules</code> del destino." },
|
||||
{ "phase": "3 — Copia de ficheros whitelisted", "detail": "<code>_rs_hyd_files</code> copia ficheros escritos por el usuario del staging rootfs al destino en vivo cuando el contenido difiere. La whitelist cubre ficheros VFIO/nvidia/blacklist bajo <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, y la regla VFIO bind + reglas udev de nvidia de ProxMenux bajo <code>/etc/udev/rules.d</code>. Los ficheros propiedad de la distro (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) se excluyen intencionadamente — sus contenidos evolucionan entre releases." },
|
||||
{ "phase": "4 — Forzar reflows post-arranque", "detail": "Las cuatro fases escriben directamente en el destino vivo FUERA del pipeline normal de restauración. Para que los tokens/módulos/ficheros mergeados tengan efecto en el siguiente arranque, <code>HB_HYDRATION_APPLIED=1</code> se propaga a través de <code>plan.env</code> a <code>apply_pending_restore.sh</code>, que fuerza <code>NEEDS_INITRAMFS=1</code> y <code>NEEDS_GRUB=1</code> con independencia de lo que hubiera en la lista de apply. El dispatcher post-arranque después regenera el initramfs y refresca el bootloader." }
|
||||
{
|
||||
"phase": "1a — Ruta GRUB",
|
||||
"detail": "Para hosts que usan GRUB (instalaciones ext4/lvm). <code>_rs_hyd_grub</code> mergea cada token de <code>manifest.kernel_params.cmdline_extra</code> de la copia en el <code>GRUB_CMDLINE_LINUX_DEFAULT</code> vivo del destino, saltando los tokens cuya clave el destino ya lleva. Después mergea claves whitelisted <code>GRUB_*</code> (<code>GRUB_TIMEOUT</code>, <code>GRUB_TIMEOUT_STYLE</code>, <code>GRUB_DEFAULT</code>, <code>GRUB_TERMINAL</code>, <code>GRUB_DISABLE_OS_PROBER</code>, <code>GRUB_SERIAL_COMMAND</code>, <code>GRUB_GFXMODE</code>, <code>GRUB_GFXPAYLOAD_LINUX</code>) del <code>/etc/default/grub</code> de la copia si difieren de las del destino."
|
||||
},
|
||||
{
|
||||
"phase": "1b — Ruta systemd-boot / ZFS",
|
||||
"detail": "Para hosts que usan systemd-boot (típicamente ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> mergea los tokens del usuario de <code>cmdline_extra</code> en el <code>/etc/kernel/cmdline</code> del destino, manteniendo intacto el boilerplate propio del destino: <code>root=</code>, <code>boot=</code> y <code>rootflags=</code>."
|
||||
},
|
||||
{
|
||||
"phase": "2 — Merge en /etc/modules",
|
||||
"detail": "<code>_rs_hyd_modules</code> añade los módulos de <code>manifest.kernel_params.modules_loaded_at_boot</code> que estén en la whitelist (<code>vfio</code>, <code>vfio_pci</code>, <code>vfio_iommu_type1</code>, <code>vfio_virqfd</code>, <code>kvm</code>, <code>kvm_intel</code>, <code>kvm_amd</code>, <code>nvidia</code>, <code>nvidia_drm</code>, <code>nvidia_modeset</code>, <code>nvidia_uvm</code>, <code>i915</code>, <code>xe</code>) Y que aún no estén presentes en <code>/etc/modules</code> del destino."
|
||||
},
|
||||
{
|
||||
"phase": "3 — Copia de ficheros whitelisted",
|
||||
"detail": "<code>_rs_hyd_files</code> copia ficheros escritos por el usuario del staging rootfs al destino en vivo cuando el contenido difiere. La whitelist cubre ficheros VFIO/nvidia/blacklist bajo <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, y la regla VFIO bind + reglas udev de nvidia de ProxMenux bajo <code>/etc/udev/rules.d</code>. Los ficheros propiedad de la distro (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) se excluyen intencionadamente — sus contenidos evolucionan entre releases."
|
||||
},
|
||||
{
|
||||
"phase": "4 — Forzar reflows post-arranque",
|
||||
"detail": "Las cuatro fases escriben directamente en el destino vivo FUERA del pipeline normal de restauración. Para que los tokens/módulos/ficheros mergeados tengan efecto en el siguiente arranque, <code>HB_HYDRATION_APPLIED=1</code> se propaga a través de <code>plan.env</code> a <code>apply_pending_restore.sh</code>, que fuerza <code>NEEDS_INITRAMFS=1</code> y <code>NEEDS_GRUB=1</code> con independencia de lo que hubiera en la lista de apply. El dispatcher post-arranque después regenera el initramfs y refresca el bootloader."
|
||||
}
|
||||
]
|
||||
},
|
||||
"planCommit": {
|
||||
@@ -59,14 +106,20 @@
|
||||
"flowDiagram": {
|
||||
"heading": "El flujo cuando el kernel del destino es más reciente que el de la copia",
|
||||
"intro": "Los pasos específicos que se añaden cuando el kernel del destino es más reciente se insertan dentro del flujo normal de restauración. Todo lo demás — hot apply, prepare pending, instalación de paquetes, dispatcher post-arranque — corre idéntico a una restauración con el mismo kernel.",
|
||||
"diagram": " ┌────────────────────────────────────────────────────────────┐\n │ hb_compat_check │\n │ HB_COMPAT_KERNEL_DIRECTION = bk_older │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Añade 16 rutas críticas del arranque a RS_SKIP_PATHS │\n │ /etc/default/grub, /etc/kernel, /etc/modules-load.d, ... │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"plan\" │\n │ Calcula qué se mergearía │\n │ Rellena RS_HYDRATION_SUMMARY (bloque verde) │\n │ Sin escrituras │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Diálogo de confirmación │\n │ Ámbar: rutas saltadas por el filtro de subconjunto seguro │\n │ Verde: tokens/ficheros reaplicados por la hidratación │\n │ El usuario acepta o cancela │\n └───────────────────────────┬────────────────────────────────┘\n │ (aceptado)\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"commit\" │\n │ Fase 1a/1b: mergea tokens del cmdline + claves GRUB │\n │ Fase 2: añade módulos a /etc/modules │\n │ Fase 3: copia ficheros whitelisted vfio/nvidia │\n │ Fija HB_HYDRATION_APPLIED=1 │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ El resto de la restauración corre normalmente │\n │ _rs_apply hot (salta RS_SKIP_PATHS) │\n │ _rs_prepare_pending_restore (escribe plan.env con │\n │ HB_HYDRATION_APPLIED=1) │\n │ packages.manual.list install │\n │ Reinicio │\n │ apply_pending_restore.sh (fuerza NEEDS_INITRAMFS=1, │\n │ NEEDS_GRUB=1 por el flag de hidratación) │\n │ apply_cluster_postboot.sh │\n │ update-initramfs -u -k all │\n │ update-grub / proxmox-boot-tool refresh │\n │ component --auto-reinstall │\n └────────────────────────────────────────────────────────────┘"
|
||||
"diagram": " ┌────────────────────────────────────────────────────────────┐\n │ hb_compat_check │\n │ HB_COMPAT_KERNEL_DIRECTION = bk_older │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Add 16 boot-critical paths to RS_SKIP_PATHS │\n │ /etc/default/grub, /etc/kernel, /etc/modules-load.d, ... │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"plan\" │\n │ Compute what would be merged │\n │ Populate RS_HYDRATION_SUMMARY (green block) │\n │ No writes │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Confirmation dialog │\n │ Amber: paths skipped by safe-subset filter │\n │ Green: tokens/files reapplied by hydration │\n │ User accepts or cancels │\n └───────────────────────────┬────────────────────────────────┘\n │ (accepted)\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ _rs_apply_bk_older_hydration \"commit\" │\n │ Phase 1a/1b: merge cmdline tokens + GRUB keys │\n │ Phase 2: append modules to /etc/modules │\n │ Phase 3: copy whitelisted vfio/nvidia files │\n │ Set HB_HYDRATION_APPLIED=1 │\n └───────────────────────────┬────────────────────────────────┘\n │\n ▼\n ┌────────────────────────────────────────────────────────────┐\n │ Rest of the restore runs normally │\n │ _rs_apply hot (skips RS_SKIP_PATHS) │\n │ _rs_prepare_pending_restore (writes plan.env with │\n │ HB_HYDRATION_APPLIED=1) │\n │ packages.manual.list install │\n │ Reboot │\n │ apply_pending_restore.sh (forces NEEDS_INITRAMFS=1, │\n │ NEEDS_GRUB=1 because of the hydration flag) │\n │ apply_cluster_postboot.sh │\n │ update-initramfs -u -k all │\n │ update-grub / proxmox-boot-tool refresh │\n │ component --auto-reinstall │\n └────────────────────────────────────────────────────────────┘"
|
||||
},
|
||||
"concreteExamples": {
|
||||
"heading": "Ejemplos concretos",
|
||||
"intro": "La pasada de hidratación no es abstracta — produce resultados observables y correctos en escenarios habituales. Dos ejemplos que la hidratación resuelve automáticamente:",
|
||||
"rows": [
|
||||
{ "scenario": "GPU passthrough (VFIO)", "detail": "El origen tenía <code>intel_iommu=on iommu=pt</code> en el cmdline, <code>vfio</code>/<code>vfio_pci</code>/<code>vfio_iommu_type1</code> en <code>/etc/modules</code>, un <code>/etc/modprobe.d/vfio.conf</code> con <code>options vfio-pci ids=10de:2216</code>, y un <code>/etc/modprobe.d/blacklist-nvidia.conf</code>. La hidratación mergea los tokens del cmdline en el GRUB o kernel cmdline del destino, añade los módulos vfio a <code>/etc/modules</code>, y copia los dos ficheros modprobe escritos por el usuario. En el siguiente arranque, IOMMU está activo, los módulos VFIO cargan, la GPU queda ligada a vfio-pci y la VM arranca con el passthrough funcionando." },
|
||||
{ "scenario": "Defaults custom de GRUB", "detail": "El origen tenía <code>GRUB_TIMEOUT=1</code> y <code>GRUB_DISABLE_OS_PROBER=true</code>. La hidratación lee ambas claves del <code>/etc/default/grub</code> de la copia, ve que difieren de los defaults de la instalación fresca, y reescribe esas dos líneas en el fichero del destino (dejando todo lo demás, incluido <code>GRUB_DISTRIBUTOR</code>, intacto)." }
|
||||
{
|
||||
"scenario": "Paso GPU (VFIO)",
|
||||
"detail": "El origen tenía <code>intel_iommu=on iommu=pt</code> en el cmdline, <code>vfio</code>/<code>vfio_pci</code>/<code>vfio_iommu_type1</code> en <code>/etc/modules</code>, un <code>/etc/modprobe.d/vfio.conf</code> con <code>options vfio-pci ids=10de:2216</code>, y un <code>/etc/modprobe.d/blacklist-nvidia.conf</code>. La hidratación mergea los tokens del cmdline en el GRUB o kernel cmdline del destino, añade los módulos vfio a <code>/etc/modules</code>, y copia los dos ficheros modprobe escritos por el usuario. En el siguiente arranque, IOMMU está activo, los módulos VFIO cargan, la GPU queda ligada a vfio-pci y la VM arranca con el passthrough funcionando."
|
||||
},
|
||||
{
|
||||
"scenario": "Defaults custom de GRUB",
|
||||
"detail": "El origen tenía <code>GRUB_TIMEOUT=1</code> y <code>GRUB_DISABLE_OS_PROBER=true</code>. La hidratación lee ambas claves del <code>/etc/default/grub</code> de la copia, ve que difieren de los defaults de la instalación fresca, y reescribe esas dos líneas en el fichero del destino (dejando todo lo demás, incluido <code>GRUB_DISTRIBUTOR</code>, intacto)."
|
||||
}
|
||||
]
|
||||
},
|
||||
"callout": {
|
||||
@@ -77,18 +130,41 @@
|
||||
"heading": "Dónde viven los mecanismos",
|
||||
"intro": "Para desarrolladores que quieran trazar o extender el comportamiento cross-kernel:",
|
||||
"rows": [
|
||||
{ "component": "Detección de dirección", "location": "<code>hb_compat_check</code> en <code>lib_host_backup_common.sh</code>. Fija <code>HB_COMPAT_KERNEL_DIRECTION</code>." },
|
||||
{ "component": "Lista de rutas del subconjunto seguro", "location": "<code>hb_unsafe_paths_cross_version</code> en <code>lib_host_backup_common.sh</code>. Emite líneas <code>path\\tmotivo</code> usadas tanto por el filtro CLI como por el endpoint Web <code>/api/host-backups/restore/prepare</code>." },
|
||||
{ "component": "Fases de hidratación", "location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> en <code>backup_host.sh</code>. Orquestados por <code>_rs_apply_bk_older_hydration</code>." },
|
||||
{ "component": "Forzado de reflow post-arranque", "location": "<code>apply_pending_restore.sh</code> lee <code>HB_HYDRATION_APPLIED</code> de <code>plan.env</code> y fuerza <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>." },
|
||||
{ "component": "Preview Web", "location": "<code>/api/host-backups/restore/prepare</code> en <code>flask_server.py</code>. Fuentea la librería helper, ejecuta <code>_rs_apply_bk_older_hydration</code> en modo plan, devuelve las acciones al modal Web." }
|
||||
{
|
||||
"component": "Detección de dirección",
|
||||
"location": "<code>hb_compat_check</code> en <code>lib_host_backup_common.sh</code>. Fija <code>HB_COMPAT_KERNEL_DIRECTION</code>."
|
||||
},
|
||||
{
|
||||
"component": "Lista de rutas del subconjunto seguro",
|
||||
"location": "<code>hb_unsafe_paths_cross_version</code> en <code>lib_host_backup_common.sh</code>. Emite líneas <code>path\\treason</code> usadas tanto por el filtro CLI como por el endpoint Web <code>/api/host-backups/restore/prepare</code>."
|
||||
},
|
||||
{
|
||||
"component": "Fases de hidratación",
|
||||
"location": "<code>_rs_hyd_grub</code>, <code>_rs_hyd_kernel_cmdline</code>, <code>_rs_hyd_modules</code>, <code>_rs_hyd_files</code> en <code>backup_host.sh</code>. Orquestados por <code>_rs_apply_bk_older_hydration</code>."
|
||||
},
|
||||
{
|
||||
"component": "Forzado de reflow post-arranque",
|
||||
"location": "<code>apply_pending_restore.sh</code> lee <code>HB_HYDRATION_APPLIED</code> de <code>plan.env</code> y fuerza <code>NEEDS_INITRAMFS=1</code>/<code>NEEDS_GRUB=1</code>."
|
||||
},
|
||||
{
|
||||
"component": "Preview Web",
|
||||
"location": "<code>/api/host-backups/restore/prepare</code> en <code>flask_server.py</code>. Fuentea la librería helper, ejecuta <code>_rs_apply_bk_older_hydration</code> en modo plan, devuelve las acciones al modal Web."
|
||||
}
|
||||
]
|
||||
},
|
||||
"whereNext": {
|
||||
"heading": "A dónde seguir",
|
||||
"items": [
|
||||
{ "label": "Restaurar", "href": "/docs/backup-restore/restoring", "tail": " — el pipeline completo de restauración en el que se enchufan los mecanismos de esta página." },
|
||||
{ "label": "Cómo funciona", "href": "/docs/backup-restore/how-it-works", "tail": " — el manifiesto y los colectores que producen el bloque <code>kernel_params</code> del que lee la hidratación." }
|
||||
{
|
||||
"label": "Restaurar",
|
||||
"href": "/docs/backup-restore/restoring",
|
||||
"tail": " — el pipeline completo de restauración en el que se enchufan los mecanismos de esta página."
|
||||
},
|
||||
{
|
||||
"label": "Cómo funciona",
|
||||
"href": "/docs/backup-restore/how-it-works",
|
||||
"tail": " — el manifiesto y los colectores que producen el bloque <code>kernel_params</code> del que lee la hidratación."
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"header": {
|
||||
"title": "Borg",
|
||||
"description": "El destino Borg escribe las copias del host en un repositorio Borg. Se soportan tres tipos de repositorio: ruta local de sistema de ficheros, disco externo montado o servidor remoto vía SSH. Deduplicación a nivel de chunk entre todos los archivos del repositorio y cifrado opcional repokey.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"aboutBorg": {
|
||||
"heading": "Qué es Borg",
|
||||
@@ -62,7 +62,7 @@
|
||||
},
|
||||
{
|
||||
"type": "local",
|
||||
"url": "/backup/borgbackup (cualquier ruta absoluta)",
|
||||
"url": "/backup/borgbackup (any absolute path)",
|
||||
"detail": "El repositorio vive en un directorio local. Sólo tiene sentido cuando el directorio está en un disco físico distinto — un repositorio en el mismo disco que el origen protege contra error humano pero no contra fallo de disco."
|
||||
}
|
||||
]
|
||||
@@ -78,7 +78,7 @@
|
||||
"Otro host Proxmox en la misma LAN, o una VM en cualquier lugar alcanzable por SSH."
|
||||
],
|
||||
"lxcWarningTitle": "LXC como servidor Borg",
|
||||
"lxcWarningBody": "Si el servidor Borg se ejecuta dentro de un LXC, el contenedor debe tener una cuenta de usuario con contraseña.",
|
||||
"lxcWarningBody": "Si el servidor Borg está en un LXC, generate-auto necesita una cuenta que acepte autenticación SSH por contraseña durante la instalación de la clave. Si no está disponible, utiliza la instalación manual de la clave o la alternativa generate-pct a través del host PVE.",
|
||||
"requirementsTitle": "Requisitos en el servidor",
|
||||
"requirementsRows": [
|
||||
{
|
||||
@@ -101,18 +101,18 @@
|
||||
"minimalSetupTitle": "Setup mínimo del servidor",
|
||||
"minimalSetupBody": "En un servidor Borg Debian o Ubuntu, un baseline funcional son cuatro comandos como root:",
|
||||
"minimalSetupCmd": "apt install borgbackup\nuseradd -m -d /home/borg -s /bin/bash borg\nmkdir -p /backup/borgbackup\nchown borg:borg /backup/borgbackup",
|
||||
"minimalSetupNote": "Tras esto, el modo <code>generate-auto</code> de ProxMenux puede conectarse usando la contraseña del usuario borg una vez, instalar su propia clave SSH, y cada copia posterior usa esa clave. No hace falta más configuración en el servidor — la clave se restringe a sí misma a <code>borg serve</code> sobre esa ruta."
|
||||
"minimalSetupNote": "Con el servidor preparado y la autenticación SSH por contraseña disponible, <code>generate-auto</code> instala la clave mediante una cuenta que pueda escribir en authorized_keys del usuario borg. Las copias posteriores usan esa clave, restringida a <code>borg serve</code> en la ruta configurada. Si no hay acceso por contraseña, instala la clave manualmente o usa la alternativa a través del host PVE."
|
||||
},
|
||||
"sshAuth": {
|
||||
"heading": "Autenticación SSH (lado cliente)",
|
||||
"intro": "Los repositorios Borg remotos se acceden vía SSH. La conexión va desde el host ProxMenux a una cuenta de usuario en el servidor Borg que ejecuta <code>borg serve</code>. Ese usuario se llama típicamente <code>borg</code>, NO el usuario admin/root del servidor — la línea de comando de borg-serve bloquea la conexión a esa ruta concreta del repositorio (ver las estrategias de clave más abajo).",
|
||||
"strategiesTitle": "Las cuatro estrategias de clave",
|
||||
"strategiesIntro": "Al añadir un destino remoto, ProxMenux pregunta por el usuario SSH, host y ruta remota, y a continuación pregunta cómo autenticar. Cuatro modos:",
|
||||
"strategiesTitle": "Estrategias de clave SSH",
|
||||
"strategiesIntro": "Al añadir un destino remoto, ProxMenux pide el usuario SSH, el host y la ruta remota, y ofrece cuatro opciones de autenticación. Si se rechaza la autenticación por contraseña, también ofrece generate-pct. Los modos se describen a continuación:",
|
||||
"strategyRows": [
|
||||
{
|
||||
"mode": "generate-auto",
|
||||
"label": "Recomendado",
|
||||
"detail": "ProxMenux genera una nueva keypair ed25519 en <code>~/.ssh/borg_proxmenux_HOST_ed25519</code>, y a continuación usa <code>sshpass</code> para hacer login UNA VEZ en el servidor con la contraseña de admin y añadir la clave pública a <code>~borg/.ssh/authorized_keys</code>. La contraseña de admin se usa sólo para esa única llamada — nunca se almacena."
|
||||
"detail": "ProxMenux genera o reutiliza un par de claves ed25519 en <code>~/.ssh/borg_proxmenux_HOST_ed25519</code> y usa <code>sshpass</code> para probar el acceso e instalar la clave pública en <code>~borg/.ssh/authorized_keys</code>. La contraseña es de una cuenta que pueda escribir ese archivo, normalmente root o el usuario borg. Se utiliza durante la configuración y no se guarda."
|
||||
},
|
||||
{
|
||||
"mode": "generate-manual",
|
||||
@@ -153,11 +153,11 @@
|
||||
"content": "Passphrase del destino con el NAME dado arriba (<code>chmod 600</code>). Sólo está presente si el usuario eligió cifrado repokey."
|
||||
}
|
||||
],
|
||||
"outro": "Guardar es opcional — el usuario puede rechazar el prompt de guardado para una copia puntual que no deje credenciales en el host."
|
||||
"outro": "Guardar el destino es opcional. Si se rechaza, no se guarda la configuración del destino con nombre, pero no se elimina una clave SSH generada. Si se activa repokey sin guardar el destino, ProxMenux guarda igualmente la frase de contraseña en el archivo heredado borg-pass.txt."
|
||||
},
|
||||
"encryption": {
|
||||
"heading": "Cifrado",
|
||||
"body": "Los repositorios se inicializan con un modo de cifrado vía <code>hb_borg_init_if_needed</code>: <code>borg repo-create -e MODE</code> en versiones modernas, o el legacy <code>borg init --encryption=MODE</code>. ProxMenux expone dos modos: <code>repokey</code> (por defecto) y <code>none</code>. En modo <code>repokey</code>, Borg almacena la clave de cifrado dentro del propio repositorio; el acceso requiere una passphrase, que ProxMenux pregunta dos veces con validación de coincidencia y guarda en <code>borg-pass-NAME.txt</code>. Un diálogo de reconocimiento obligatorio se muestra tras guardar la passphrase: la passphrase es la única manera de acceder a los archivos cifrados, y perderla hace irrecuperable todo archivo del repositorio."
|
||||
"body": "Los repositorios se inicializan con un modo de cifrado vía <code>hb_borg_init_if_needed</code>: <code>borg repo-create -e MODE</code> en versiones modernas, o el legacy <code>borg init --encryption=MODE</code>. ProxMenux expone dos modos: <code>repokey</code> (por defecto) y <code>none</code>. En modo <code>repokey</code>, Borg almacena la clave de cifrado dentro del propio repositorio; el acceso requiere una passphrase, que ProxMenux pregunta dos veces con validación de coincidencia y guarda en <code>borg-pass-NAME.txt</code> para destinos guardados, o en el archivo heredado descrito antes. Un diálogo de reconocimiento obligatorio se muestra tras guardar la passphrase: la passphrase es la única manera de acceder a los archivos cifrados, y perderla hace irrecuperable todo archivo del repositorio."
|
||||
},
|
||||
"runtimeEnv": {
|
||||
"heading": "Entorno de ejecución",
|
||||
@@ -165,8 +165,8 @@
|
||||
"rows": [
|
||||
{
|
||||
"var": "BORG_RSH",
|
||||
"value": "ssh -i SSH_KEY_PATH -o StrictHostKeyChecking=accept-new",
|
||||
"purpose": "El comando de shell remoto que Borg usa para repositorios servidos por SSH. Se fija sólo cuando se seleccionó una clave personalizada; en caso contrario queda sin definir para que Borg use la configuración SSH por defecto."
|
||||
"value": "ssh -i SSH_KEY_PATH -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new [-p PORT]",
|
||||
"purpose": "Comando de shell remoto que Borg utiliza para repositorios SSH. Elegir una clave añade las opciones de identidad; un puerto distinto del predeterminado añade -p PORT. Sin clave personalizada y con el puerto predeterminado, la variable queda sin definir y Borg usa la configuración SSH del host."
|
||||
},
|
||||
{
|
||||
"var": "BORG_PASSPHRASE",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"header": {
|
||||
"title": "Destinos",
|
||||
"description": "Los tres backends de almacenamiento soportados por ProxMenux Backup: archivo local, Proxmox Backup Server (recomendado) y Borg. Cada uno recibe el mismo archivo de tres bloques; se diferencian en formato de almacenamiento, deduplicación, modelo de cifrado y requisitos de red.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "El mismo contenido, tres backends",
|
||||
@@ -29,8 +29,8 @@
|
||||
{
|
||||
"feature": "Compresión",
|
||||
"local": "zstd (nivel por defecto) mediante <code>tar --zstd</code>. Fallback a gzip.",
|
||||
"pbs": "Gestionada por PBS. El cliente envía sin comprimir; el servidor chunkiza + comprime.",
|
||||
"borg": "La integrada de Borg (lz4 por defecto). Configurable al inicializar el repo."
|
||||
"pbs": "La gestiona proxmox-backup-client. ProxMenux no modifica las opciones de compresión.",
|
||||
"borg": "La compresión integrada de Borg. ProxMenux ejecuta borg create sin modificar las opciones de compresión."
|
||||
},
|
||||
{
|
||||
"feature": "Deduplicación",
|
||||
@@ -69,20 +69,20 @@
|
||||
"borg": "Requiere <code>borg</code> + la ruta del repositorio + la passphrase (si está cifrado)."
|
||||
}
|
||||
],
|
||||
"captionCode": "Característica",
|
||||
"captionCode": "feature",
|
||||
"captionLocal": "Local",
|
||||
"captionPbs": "Proxmox Backup Server (recomendado)",
|
||||
"captionBorg": "Borg"
|
||||
},
|
||||
"sameArchive": {
|
||||
"heading": "El contenido interno de la copia es el mismo en cualquier destino",
|
||||
"body": "Con independencia de dónde se guarde la copia, dentro siempre están los mismos tres bloques descritos en <em>Cómo funciona</em>: el sistema de ficheros (<code>rootfs/</code>), los metadatos (<code>metadata/</code>) y el manifiesto (<code>manifest.json</code>). Al extraer una copia local <code>.tar.zst</code>, restaurar un archivo <code>.pxar</code> desde PBS o descomprimir un archivo Borg, el árbol de directorios resultante es idéntico en los tres casos. Esto significa que el proceso de restauración lee siempre los mismos ficheros y no le importa desde qué destino provenga la copia."
|
||||
"body": "Los tres destinos contienen la misma estructura <code>rootfs/</code> + <code>metadata/</code> + <code>manifest.json</code> descrita en <em>Cómo funciona</em>. Extraer un <code>.tar.zst</code> de un archivo local, restaurar un <code>.pxar</code> desde PBS o extraer un archivo de Borg con <code>borg extract</code> produce el mismo árbol de directorios. El proceso de restauración (<code>_rs_check_layout</code>, <code>_rs_apply</code>, <code>_rs_prepare_pending_restore</code>) lee los mismos tres componentes sin necesitar saber de qué destino proceden."
|
||||
},
|
||||
"extractStandalone": {
|
||||
"heading": "Extraer una copia fuera de ProxMenux",
|
||||
"intro": "Cualquiera de los tres formatos de archivo se puede leer con herramientas estándar sin tener ProxMenux instalado en el host de lectura. Los comandos siguientes producen el mismo árbol de directorios que consume internamente una restauración.",
|
||||
"localCmd": "# Desde un archivo local .tar.zst:\ntar --zstd -xf hostcfg-HOST-TIMESTAMP.tar.zst\n\n# Desde el fallback .tar.gz:\ntar -xzf hostcfg-HOST-TIMESTAMP.tar.gz",
|
||||
"pbsCmd": "# Desde un backup PBS (requiere proxmox-backup-client):\nproxmox-backup-client restore \\\n --repository USER@REALM@HOST:DATASTORE \\\n host/hostcfg-HOST/BACKUP-TIME \\\n hostcfg.pxar /tmp/hostcfg\n\n# Añadir --keyfile KEY-PATH cuando el backup está cifrado.",
|
||||
"localCmd": "# From a local .tar.zst archive:\ntar --zstd -xf hostcfg-HOST-TIMESTAMP.tar.zst\n\n# From a .tar.gz fallback:\ntar -xzf hostcfg-HOST-TIMESTAMP.tar.gz",
|
||||
"pbsCmd": "# From a PBS backup (requires proxmox-backup-client):\nproxmox-backup-client restore \\\n --repository USER@REALM@HOST:DATASTORE \\\n host/hostcfg-HOST/BACKUP-TIME \\\n hostcfg.pxar /tmp/hostcfg\n\n# Add --keyfile KEY-PATH when the backup is encrypted.",
|
||||
"borgCmd": "# Desde un archivo Borg (requiere el binario borg + passphrase si hay cifrado):\nborg extract REPO-PATH::ARCHIVE-NAME\n\n# Sobre un repo servido por SSH:\nborg extract ssh://USER@HOST:PORT/REPO-PATH::ARCHIVE-NAME",
|
||||
"note": "El árbol extraído puede inspeccionarse manualmente o alimentar una restauración manual. Consulta las páginas de cada destino para conocer el flujo exacto de recuperación que ProxMenux utiliza por dentro."
|
||||
},
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"header": {
|
||||
"title": "Archivo local",
|
||||
"description": "El destino local escribe un único archivo tar comprimido en cualquier directorio escribible del host: un disco interno, un montaje NFS o SMB, o una unidad USB.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Un solo fichero, autocontenido",
|
||||
@@ -31,17 +31,17 @@
|
||||
"statesTitle": "Los tres estados del dispositivo",
|
||||
"stateRows": [
|
||||
{
|
||||
"state": "mounted",
|
||||
"shown": "Tamaño · label · [fstype] · → /punto/de/montaje",
|
||||
"state": "montado",
|
||||
"shown": "Tamaño · etiqueta · [fstype] · → /mount/point",
|
||||
"action": "La partición ya está montada en algún sitio. Seleccionarla persiste ese punto de montaje como destino local. No se realiza ningún montaje."
|
||||
},
|
||||
{
|
||||
"state": "unmounted",
|
||||
"state": "sin montar",
|
||||
"shown": "Tamaño · label · [fstype] · (no montada — se montará)",
|
||||
"action": "Hay un filesystem pero no está montado. Al confirmar, ProxMenux ejecuta <code>hb_mount_usb_partition</code>: crea <code>/mnt/backup-LABEL</code> (o una ruta basada en UUID si no hay label), monta la partición y persiste el punto de montaje como destino local."
|
||||
},
|
||||
{
|
||||
"state": "empty",
|
||||
"state": "vacía",
|
||||
"shown": "Tamaño · disco USB en crudo — sin filesystem (se FORMATEARÁ)",
|
||||
"action": "El dispositivo no tiene filesystem. Camino destructivo — protegido por dos confirmaciones. Primero un diálogo Yes/No explica que la operación borrará el disco. Después una caja de entrada obliga al usuario a <strong>escribir la ruta exacta del dispositivo</strong> (por ejemplo <code>/dev/sdb</code>) antes de que ProxMenux cree una partición GPT + ext4 fresca y la monte."
|
||||
}
|
||||
@@ -50,7 +50,7 @@
|
||||
},
|
||||
"safetyCheck": {
|
||||
"heading": "Chequeo de seguridad — destino dentro de una ruta copiada",
|
||||
"body": "Antes de escribir el archivo, <code>_bk_local</code> verifica que el directorio de destino <strong>no</strong> sea un subcamino de ninguno de los directorios que se están copiando. Un footgun habitual sería añadir <code>/root</code> al perfil y elegir <code>/root/backups</code> como destino — el archivo se incluiría a sí mismo, produciendo o bien un archivo corrupto o bien crecimiento sin límite hasta llenar el disco. El chequeo resuelve ambos caminos con <code>readlink -m</code>, los compara y, si hay conflicto, aborta la copia con un diálogo que nombra la ruta en conflicto y lista tres formas de resolverlo: elegir un destino fuera de la ruta en conflicto, eliminar la entrada personalizada que contiene el destino, o usar modo Custom para desmarcar la ruta en conflicto en esa ejecución."
|
||||
"body": "Antes de escribir el archivo, <code>_bk_local</code> verifica que el directorio de destino <strong>no</strong> sea un subcamino de ninguno de los directorios que se están copiando. Un error habitual sería añadir <code>/root</code> al perfil y elegir <code>/root/backups</code> como destino — el archivo se incluiría a sí mismo, produciendo o bien un archivo corrupto o bien crecimiento sin límite hasta llenar el disco. El chequeo resuelve ambos caminos con <code>readlink -m</code>, los compara y, si hay conflicto, aborta la copia con un diálogo que nombra la ruta en conflicto y lista tres formas de resolverlo: elegir un destino fuera de la ruta en conflicto, eliminar la entrada personalizada que contiene el destino, o usar modo Custom para desmarcar la ruta en conflicto en esa ejecución."
|
||||
},
|
||||
"archiveFormat": {
|
||||
"heading": "Formato de archivo y compresión",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"meta": {
|
||||
"title": "Destino Proxmox Backup Server — repositorio, cifrado, recuperación | ProxMenux",
|
||||
"description": "El destino PBS escribe las copias de host de ProxMenux como backups PBS. Documenta la auto-detección del repositorio desde /etc/pve/storage.cfg, la configuración manual de PBS, el comando de subida .pxar, el modelo de cifrado por keyfile del lado del cliente, el blob de escrow con passphrase de recuperación, y la recuperación del keyfile desde PBS en instalaciones frescas.",
|
||||
"description": "El destino PBS guarda las copias del host de ProxMenux como copias PBS. Explica la detección de repositorios desde /etc/pve/storage.cfg, la configuración manual, la subida de .pxar, el cifrado con archivo de clave en el cliente y su custodia opcional protegida por una frase de contraseña, y la recuperación de la clave desde varias fuentes en un host recién instalado.",
|
||||
"ogTitle": "ProxMenux Backup — destino Proxmox Backup Server",
|
||||
"ogDescription": "Cómo escribe ProxMenux las copias de host en Proxmox Backup Server con cifrado por keyfile del lado del cliente y escrow de recuperación.",
|
||||
"twitterTitle": "Destino PBS de copia | ProxMenux",
|
||||
@@ -9,8 +9,8 @@
|
||||
},
|
||||
"header": {
|
||||
"title": "Proxmox Backup Server",
|
||||
"description": "El destino PBS sube la raíz de staging como un único backup .pxar a un datastore de Proxmox Backup Server, con cifrado opcional por keyfile del lado del cliente y escrow automático de una passphrase de recuperación para recuperación tras reinstalación.",
|
||||
"section": "Backup & Restore"
|
||||
"description": "El destino PBS sube todo el directorio de preparación como una única copia .pxar a un datastore de Proxmox Backup Server. Permite cifrarla en el cliente con un archivo de clave y, de forma opcional, subir junto a cada copia una copia de la clave protegida por una frase de contraseña para recuperarla después.",
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"recommendedBadge": "Destino recomendado",
|
||||
"aboutPbs": {
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"repoSelection": {
|
||||
"heading": "Selección del repositorio",
|
||||
"intro": "ProxMenux descubre repositorios PBS desde dos fuentes en cada copia. El usuario elige uno desde un menú unificado; esa elección determina, para esa ejecución concreta, contra qué servidor y datastore se envía la copia, con qué contraseña se autentica y con qué huella (<em>fingerprint</em>) valida el certificado.",
|
||||
"intro": "ProxMenux descubre los repositorios de PBS a partir de dos fuentes en cada copia de seguridad. El usuario elige uno en un menú unificado; esa elección determina los valores de <code>HB_PBS_REPOSITORY</code>, <code>HB_PBS_SECRET</code> y <code>HB_PBS_FINGERPRINT</code> para esa ejecución.",
|
||||
"sourceRows": [
|
||||
{
|
||||
"source": "storage.cfg de Proxmox (auto-descubierto)",
|
||||
@@ -41,12 +41,12 @@
|
||||
},
|
||||
"backupCommand": {
|
||||
"heading": "El comando de copia",
|
||||
"intro": "La subida es una única invocación de <code>proxmox-backup-client backup</code>. ProxMenux la ejecuta dentro de un envoltorio <code>env</code> para que las credenciales nunca aparezcan en la lista de argumentos del proceso.",
|
||||
"intro": "La subida se realiza con una única invocación de <code>proxmox-backup-client backup</code>. ProxMenux utiliza <code>env</code> para pasar al cliente la contraseña, la contraseña de cifrado y el fingerprint como variables de entorno.",
|
||||
"cmd": "env \\\n PBS_PASSWORD=\"$HB_PBS_SECRET\" \\\n PBS_ENCRYPTION_PASSWORD=\"$HB_PBS_ENC_PASS\" \\\n PBS_FINGERPRINT=\"$HB_PBS_FINGERPRINT\" \\\n proxmox-backup-client backup \\\n hostcfg.pxar:$staging_root \\\n --repository USER@REALM@HOST:DATASTORE \\\n --backup-type host \\\n --backup-id hostcfg-HOSTNAME \\\n --backup-time BACKUP-EPOCH \\\n [--keyfile /usr/local/share/proxmenux/pbs-key.conf]",
|
||||
"backupIdTitle": "Nombrado del backup ID",
|
||||
"backupIdBody": "El backup ID por defecto es <code>hostcfg-HOSTNAME</code>. Se pide al usuario que lo confirme o edite antes de la subida; cualquier carácter fuera de <code>[A-Za-z0-9_-]</code> se elimina y los guiones finales se recortan. Reutilizar el mismo ID entre ejecuciones es intencional — PBS trata el ID como un <em>grupo</em>, y cada copia posterior aparece como un nuevo backup dentro de ese grupo, compartiendo dedup con las ejecuciones previas.",
|
||||
"pxarTitle": "Qué se incluye dentro del archivo .pxar",
|
||||
"pxarBody": "Al construir el archivo <code>.pxar</code> se empaqueta el directorio de trabajo completo: el sistema de ficheros del host (<code>rootfs/</code>), los metadatos (<code>metadata/</code>) y el manifiesto (<code>manifest.json</code>). Al restaurar, ProxMenux compara la información del manifiesto con la del host destino para detectar si son equivalentes, si cambia el hardware o si se trata de un equipo distinto, y ajustar el proceso en consecuencia. Las copias antiguas —hechas con versiones anteriores de ProxMenux que empaquetaban solo el sistema de ficheros— siguen restaurándose sin problema: el flujo de restauración detecta ese formato heredado y lo reorganiza automáticamente."
|
||||
"pxarBody": "El origen del <code>.pxar</code> es todo el directorio <code>staging_root</code>, con <code>rootfs/</code>, <code>metadata/</code> y <code>manifest.json</code> juntos. Las versiones anteriores utilizaban <code>$staging_root/rootfs</code> como origen; esto dejaba <code>metadata/</code> fuera del archivo y la comprobación de compatibilidad de la restauración no tenía datos que leer, por lo que mostraba advertencias de restauración entre hosts incluso al restaurar en el mismo host. Las copias antiguas creadas solo a partir de rootfs siguen restaurándose correctamente mediante la rama del caso 3 de <code>_rs_check_layout</code>, que vuelve a colocar el árbol plano <code>etc/var/root/usr</code> dentro de una estructura <code>rootfs/</code>."
|
||||
},
|
||||
"encryption": {
|
||||
"heading": "Cifrado del lado del cliente",
|
||||
@@ -61,19 +61,19 @@
|
||||
"modesSharedTitle": "Clave compartida (importar la misma en cada host)",
|
||||
"modesSharedBody": "Se genera una única clave y se importa en todos los hosts mediante la opción <em>Usar una clave existente</em>. La gestión es más sencilla: hay un solo secreto que proteger, y cualquier host puede leer las copias de cualquier otro (útil para verificación centralizada, ejercicios de restauración cruzada o consolidación). A cambio, si la clave compartida se filtra queda expuesto todo el conjunto de hosts a la vez. Recomendado para laboratorios personales y entornos donde todos los hosts pertenecen al mismo responsable y comparten el mismo nivel de confianza.",
|
||||
"recoveryTitle": "¿Subir la clave a PBS? — el usuario decide",
|
||||
"recoveryBody": "Justo después de elegir la clave, ProxMenux pregunta si se quiere subir una copia de esa clave a PBS como red de seguridad, con dos opciones. <strong>No</strong> (por defecto) mantiene la clave solo en el host; ProxMenux no toca PBS con nada relacionado con la recuperación y el usuario gestiona por su cuenta la copia externa (desde el Monitor, la acción <em>Descargar</em> en la fila del destino PBS la exporta en el acto). <strong>Sí</strong> pide una passphrase de recuperación —dos veces, para comprobar que coincidan—; con esa passphrase, la clave se envuelve localmente con AES-256-CBC y PBKDF2 (600 000 iteraciones, sal aleatoria) en un fichero <code>pbs-key.recovery.enc</code>. A partir de ese momento, cada copia cifrada sube también ese fichero envuelto a PBS. Ni la passphrase ni la clave en claro salen del host. La respuesta se puede cambiar después desde el Monitor en cualquier momento; el interruptor está inline en la fila del destino PBS y el botón que aparece se adapta al estado (empezar a subir, dejar de subir, o cambiar la passphrase).",
|
||||
"recoveryBody": "Justo después de elegir la clave, ProxMenux pregunta <em>¿Subir la clave a PBS?</em>, con dos respuestas. <strong>No se sube ningún artefacto de recuperación a PBS hasta que el usuario responde Sí.</strong> Por defecto se elige <em>No, mantener solo en local</em>: la clave queda en su ruta canónica, ProxMenux no sube artefactos de recuperación a PBS y el usuario se encarga de guardarla fuera del host. El botón <em>Descargar archivo de clave</em> del Monitor, en la fila del destino PBS, permite obtenerla cuando se necesite. Al elegir <em>Sí, subir</em>, se pide dos veces una frase de contraseña de recuperación y se comprueba que coincidan. ProxMenux protege la clave con AES-256-CBC y PBKDF2 (600.000 iteraciones y sal aleatoria) para generar <code>pbs-key.recovery.enc</code>. Cada copia cifrada posterior sube esa envoltura a PBS como un grupo de copias asociado. En estas subidas no se envían a PBS ni la frase de contraseña ni la clave en texto claro. La elección puede cambiarse en cualquier momento desde el Monitor: el control de custodia de la fila del destino permite elegir Sí o No y aplicar inmediatamente Iniciar subida, Detener subida o Actualizar frase de contraseña, según el estado.",
|
||||
"blobUploadTitle": "Grupo emparejado en PBS",
|
||||
"blobUploadBody1": "Cuando el usuario ha respondido Sí, ProxMenux sube el sobre de recuperación a PBS después de cada copia cifrada como un segundo grupo emparejado, con el mismo nombre que el del host pero terminado en <code>-keyrecovery</code>. Los dos grupos aparecen juntos en el listado del datastore: uno con las copias del host, otro con los sobres. <strong>El sobre nunca sale del host en claro</strong>: se cifra en el host con AES-256-CBC y PBKDF2 antes de enviar un solo byte (<code>openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt</code>). PBS solo recibe el sobre ya cifrado.",
|
||||
"blobUploadBody1": "Cuando la custodia está configurada como <em>Sí, subir</em>, ProxMenux sube el archivo de recuperación protegido a PBS después de cada copia cifrada. Lo guarda en un segundo grupo de copia asociado, con el mismo nombre que el grupo del host y el sufijo <code>-keyrecovery</code>. Los dos grupos aparecen juntos en la lista del almacén de datos: uno para las copias del host y otro para los archivos de recuperación. <strong>El archivo de recuperación nunca sale del host en texto plano</strong>: se cifra en el propio host con AES-256-CBC y PBKDF2 antes de enviar ningún dato (<code>openssl enc -aes-256-cbc -pbkdf2 -iter 600000 -salt</code>). PBS solo recibe el archivo ya cifrado.",
|
||||
"envelopeSecurityTitle": "¿No es un riesgo subir el archivo keyrecovery a PBS?",
|
||||
"envelopeSecurityBody": "El sobre viaja y se guarda cifrado en todo momento. La passphrase de recuperación no sale nunca del host: el cifrado ocurre en local antes de la subida y PBS solo recibe el resultado ya cifrado. Un administrador de PBS —o cualquiera con acceso al datastore— puede descargar el sobre, pero sin la passphrase no puede leer la clave que contiene: son solo bytes cifrados. Para reconstruir la clave hacen falta las dos cosas a la vez, el sobre y la passphrase, y solo el usuario tiene ambas.",
|
||||
"blobUploadConstraintTitle": "Por qué dos grupos y no uno solo cifrado",
|
||||
"blobUploadConstraintBody": "Cada subida de <code>proxmox-backup-client backup</code> cifra todos sus archivos con la misma clave —o ninguno—. No hay opción intermedia. La copia del host tiene que ir cifrada con la clave. El sobre de recuperación no puede viajar en esa misma subida: quedaría cifrado con la clave que precisamente contiene, y en un equipo recién reinstalado no habría manera de abrirlo (haría falta la clave para descifrar la clave). Por eso salen dos subidas independientes y aparecen dos grupos separados: la copia del host la cifra PBS con la clave, y el sobre lo cifra ProxMenux con la passphrase antes de subirlo. Dos capas de cifrado distintas para dos cosas distintas.",
|
||||
"blobUploadConstraintBody": "Una invocación de <code>proxmox-backup-client backup</code> cifra todos sus archivos con la misma clave o no cifra ninguno; no permite mezclar ambos casos. La copia del host se cifra con su archivo de clave, pero la envoltura de recuperación no puede acompañarla en la misma subida porque acabaría cifrada con la propia clave que contiene. En un host recién reinstalado sería imposible abrirla: haría falta la clave para descifrar esa misma clave. Por eso los dos artefactos se suben por separado y aparecen en dos grupos: el cliente PBS cifra la copia del host con el archivo de clave y ProxMenux cifra la envoltura con la frase de contraseña antes de subirla. Dos capas de cifrado distintas protegen dos elementos diferentes.",
|
||||
"blobUploadImageAlt": "Interfaz de PBS mostrando los grupos hostcfg-HOSTNAME y hostcfg-HOSTNAME-keyrecovery adyacentes en el listado del datastore.",
|
||||
"blobUploadImageCaption": "Interfaz de PBS — los grupos de copia emparejados. El grupo principal contiene las copias del host; el grupo -keyrecovery contiene la clave envuelta con la passphrase.",
|
||||
"recoverTitle": "Recuperación en un equipo recién instalado",
|
||||
"recoverBody": "Cuando la clave no está en su sitio —tras reinstalar el host desde cero o después de eliminarla a propósito— el flujo de restauración prueba tres fuentes en orden y se queda con la primera que produce una clave usable. Primero, si el repositorio PBS elegido tiene una clave gestionada por PVE en <code>/etc/pve/priv/storage/<NAME>.enc</code>, se copia sola a la ruta canónica. Segundo, si en PBS hay un grupo <code>-keyrecovery</code>, se descarga la copia más reciente y se pide la passphrase de recuperación para abrirla. Tercero, si ninguna de las dos anteriores funciona o el usuario las descarta, el diálogo pide la ruta absoluta donde ha dejado la clave en este host, y se copia a la ruta canónica. El Monitor expone el mismo flujo dentro del modal de la copia. Si al Restaurar, Descargar o Ver contenido falta la clave, aparece un panel ámbar arriba del modal con las mismas tres vías de importación. Si la clave está instalada pero no es la correcta para esa copia, PBS devuelve un error de tipo <code>wrong key — manifest's key XX does not match provided key YY</code> y el modal muestra un panel estructurado con el fingerprint que PBS espera (el que quedó grabado en el manifest de la copia), para que el usuario sepa qué clave concreta necesita importar.",
|
||||
"monitorManagementTitle": "Gestionar la clave desde el Monitor",
|
||||
"monitorManagementBody": "En la página de configuración de copias, la fila de cada destino PBS incluye los controles de la clave. Tres acciones directas: <em>Descargar</em> exporta la clave actual al navegador. <em>Subir</em> reemplaza la clave instalada por otra que aporta el usuario (la anterior solo se sobrescribe cuando la nueva ha llegado correctamente a su sitio). <em>Eliminar</em> retira la clave del host. Justo al lado está el interruptor del sobre de recuperación: un Sí/No para subir o no la clave a PBS, un campo de passphrase que aparece al elegir Sí, y un botón que se adapta al estado actual (empezar a subir, dejar de subir, o cambiar la passphrase). Los controles del Monitor y el diálogo del shell hacen lo mismo por dentro, así que el resultado en disco y en PBS es idéntico se use la que se use."
|
||||
"monitorManagementBody": "El Monitor muestra los controles del archivo de clave en cada fila de destino PBS de la página de configuración de copias. Hay tres acciones: <em>Descargar</em> envía el archivo de clave actual al navegador del usuario; <em>Subir</em> sustituye el archivo de clave instalado por uno proporcionado por el usuario (el anterior solo se sobrescribe cuando el nuevo se ha guardado correctamente en la ruta canónica); y <em>Eliminar</em> borra el archivo de clave del host. Junto a estas acciones hay un único control de custodia para la recuperación: las opciones Sí y No de <em>¿Subir la clave a PBS?</em>, un campo para la frase de contraseña al elegir Sí y un botón contextual para aplicar el cambio, con el texto <em>Iniciar subida</em>, <em>Detener subida</em> o <em>Actualizar frase de contraseña</em> según el estado actual. Todas las acciones utilizan los mismos endpoints de Flask que el menú de terminal, por lo que el resultado en disco y el estado en PBS son idénticos desde ambas interfaces."
|
||||
},
|
||||
"restoreAccess": {
|
||||
"heading": "Recuperación del lado de la restauración",
|
||||
@@ -96,7 +96,7 @@
|
||||
{
|
||||
"label": "Cifrado del lado del cliente",
|
||||
"href": "https://pbs.proxmox.com/docs/backup-client.html#encryption",
|
||||
"tail": " — creación del keyfile, modos --kdf, el modelo de cifrado que ProxMenux extiende con un escrow de passphrase."
|
||||
"tail": " — creación del archivo de clave, modos --kdf y modelo de cifrado que ProxMenux amplía con una copia de recuperación protegida por frase de contraseña."
|
||||
},
|
||||
{
|
||||
"label": "Gestión de datastores",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"header": {
|
||||
"title": "Glosario",
|
||||
"description": "Términos que aparecen a lo largo de la documentación de copia y restauración, con su definición.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"body": "Los términos están agrupados por temas. Cada entrada incluye una definición breve."
|
||||
@@ -23,43 +23,36 @@
|
||||
{
|
||||
"id": "passphrase-recuperacion",
|
||||
"term": "Passphrase de recuperación",
|
||||
"also": "recovery passphrase",
|
||||
"def": "Contraseña de texto que elige el usuario para proteger el <a href=\"#sobre-recuperacion\">sobre de recuperación</a>. Se pide dos veces con validación de coincidencia y solo se usa para cifrar el sobre y para descifrarlo si algún día hay que recuperar la clave. <strong>No sirve para desbloquear la clave del keyfile</strong> ni se envía nunca a PBS. Nunca sale del host durante una copia normal."
|
||||
},
|
||||
{
|
||||
"id": "clave-cifrado",
|
||||
"term": "Clave de cifrado (keyfile)",
|
||||
"also": "keyfile, PBS encryption key",
|
||||
"def": "Fichero binario que Proxmox Backup Server utiliza para cifrar los <a href=\"#chunk\">chunks</a> de la copia antes de subirlos. Sin ese fichero, ninguna copia cifrada puede leerse. ProxMenux lo guarda en <code>/usr/local/share/proxmenux/pbs-key.conf</code> con permisos <code>600</code>. Es el activo que hay que proteger; el <a href=\"#sobre-recuperacion\">sobre de recuperación</a> existe precisamente para poder rescatar este fichero si se pierde."
|
||||
"def": "Archivo de clave que proxmox-backup-client usa para cifrar los <a href=\"#chunk\">chunks</a> antes de subirlos a PBS. Sin la clave correspondiente no se leen los datos cifrados. ProxMenux lo guarda en <code>/usr/local/share/proxmenux/pbs-key.conf</code> con modo <code>600</code>. Protégelo: el <a href=\"#sobre-recuperacion\">sobre de recuperación</a> permite recuperarlo si se pierde."
|
||||
},
|
||||
{
|
||||
"id": "contrasena-keyfile",
|
||||
"term": "Contraseña de la clave (KDF passphrase)",
|
||||
"also": "keyfile passphrase, scrypt passphrase",
|
||||
"def": "Contraseña opcional que puede llevar la propia clave, distinta de la <a href=\"#passphrase-recuperacion\">passphrase de recuperación</a>. Solo aparece si la clave se creó con <code>--kdf scrypt</code> (una clave importada de otro sitio, por ejemplo). Sin ella, la clave no se puede desbloquear en cada uso. ProxMenux la persiste cifrada en el host para que las copias programadas puedan ejecutarse sin diálogo interactivo."
|
||||
},
|
||||
{
|
||||
"id": "sobre-recuperacion",
|
||||
"term": "Sobre de recuperación",
|
||||
"also": "recovery envelope, escrow blob, pbs-key.recovery.enc",
|
||||
"def": "La propia <a href=\"#clave-cifrado\">clave de cifrado</a> envuelta en una capa adicional: se cifra con la <a href=\"#passphrase-recuperacion\">passphrase de recuperación</a> mediante <a href=\"#aes-256-cbc\">AES-256-CBC</a> y <a href=\"#pbkdf2\">PBKDF2</a> antes de salir del host. Es lo que se sube a PBS en el grupo <code>-keyrecovery</code>. Sin la passphrase, el sobre es opaco: descargarlo desde PBS no revela la clave."
|
||||
},
|
||||
{
|
||||
"id": "cifrado-cliente",
|
||||
"term": "Cifrado del lado del cliente",
|
||||
"also": "client-side encryption",
|
||||
"def": "Modelo en el que los datos se cifran en el host de origen antes de subirse. PBS solo recibe y almacena datos cifrados; ni siquiera un administrador de PBS con acceso al datastore puede leerlos sin la clave. ProxMenux se apoya en este modelo y añade el <a href=\"#sobre-recuperacion\">sobre de recuperación</a> encima."
|
||||
},
|
||||
{
|
||||
"id": "kdf-none",
|
||||
"term": "--kdf none",
|
||||
"also": "clave sin contraseña",
|
||||
"def": "Opción de <code>proxmox-backup-client key create</code> que genera una clave sin contraseña asociada. La clave se puede usar directamente sin ningún diálogo, lo que es imprescindible para que los trabajos programados corran de forma desatendida. Es lo que ProxMenux usa por defecto al generar una clave nueva."
|
||||
},
|
||||
{
|
||||
"id": "kdf-scrypt",
|
||||
"term": "--kdf scrypt",
|
||||
"also": "clave con contraseña",
|
||||
"def": "Opción de <code>proxmox-backup-client key create</code> que genera una clave protegida con una <a href=\"#contrasena-keyfile\">contraseña de la clave</a>. Cada vez que se usa la clave hay que desbloquearla con esa contraseña. ProxMenux acepta este tipo de claves al importarlas y guarda la contraseña cifrada para que las copias programadas puedan correr sin intervención."
|
||||
},
|
||||
{
|
||||
@@ -112,11 +105,11 @@
|
||||
{
|
||||
"id": "repositorio-pbs",
|
||||
"term": "Repositorio PBS",
|
||||
"def": "Combinación de servidor Proxmox Backup Server + <a href=\"#datastore\">datastore</a> + usuario al que se suben las copias. Se identifica con el formato <code>usuario@realm@host:datastore</code>. Un mismo servidor PBS puede alojar varios repositorios."
|
||||
"def": "Combinación de servidor Proxmox Backup Server + <a href=\"#datastore\">datastore</a> + usuario al que se suben las copias. Se identifica con el formato <code>user@realm@host:datastore</code>. Un mismo servidor PBS puede alojar varios repositorios."
|
||||
},
|
||||
{
|
||||
"id": "datastore",
|
||||
"term": "Datastore",
|
||||
"term": "almacén de datos",
|
||||
"def": "Almacén concreto dentro de un servidor PBS donde se guardan las copias y sus chunks. Cada datastore vive sobre un sistema de ficheros del servidor PBS y tiene sus propios permisos y políticas."
|
||||
},
|
||||
{
|
||||
@@ -136,7 +129,7 @@
|
||||
},
|
||||
{
|
||||
"id": "backup-id",
|
||||
"term": "Backup ID",
|
||||
"term": "ID del backup",
|
||||
"def": "Nombre del <a href=\"#grupo-copia\">grupo de copia</a>. ProxMenux propone por defecto <code>hostcfg-HOSTNAME</code> y permite editarlo antes de la subida; los caracteres no admitidos se limpian automáticamente."
|
||||
},
|
||||
{
|
||||
@@ -152,8 +145,8 @@
|
||||
"entries": [
|
||||
{
|
||||
"id": "runner",
|
||||
"term": "Runner",
|
||||
"def": "Script <code>run_scheduled_backup.sh</code> que ejecuta una copia programada. Lee la configuración del trabajo, lanza el backend correspondiente (Local, PBS o Borg), aplica la retención al terminar y envía las notificaciones configuradas."
|
||||
"term": "Ejecutor",
|
||||
"def": "Script <code>run_scheduled_backup.sh</code> que ejecuta una copia programada. Lee la configuración del trabajo, lanza el backend correspondiente (Local, PBS o Borg), aplica la retención tras completarse con éxito y envía las notificaciones configuradas."
|
||||
},
|
||||
{
|
||||
"id": "trabajo-programado",
|
||||
@@ -163,7 +156,7 @@
|
||||
{
|
||||
"id": "modo-adjunto",
|
||||
"term": "Modo adjunto (attach mode)",
|
||||
"def": "Trabajo programado que no lleva horario propio; se dispara automáticamente cada vez que una tarea <code>vzdump</code> de PVE existente se ejecuta. Hereda el horario y la retención de esa tarea padre. Solo compatible con destinos Local y PBS."
|
||||
"def": "Trabajo sin timer propio. Un hook job-end de <code>vzdump</code> lo ejecuta después de las copias de invitados cuando coincide el almacenamiento. El padre seleccionado aporta destino y retención inicial, pero el hook compara almacenamiento, no ID de tarea padre; otra tarea con el mismo destino también puede activarlo. Solo para Local y PBS."
|
||||
},
|
||||
{
|
||||
"id": "timer-systemd",
|
||||
@@ -203,13 +196,12 @@
|
||||
},
|
||||
{
|
||||
"id": "compatibility-check",
|
||||
"term": "Compatibility check",
|
||||
"term": "Verificación de compatibilidad",
|
||||
"def": "Comparación entre el manifiesto del origen y el estado del destino que ProxMenux realiza al principio de la restauración. Decide qué partes se copian verbatim, cuáles necesitan hidratación y cuáles se recrean desde el instalador."
|
||||
},
|
||||
{
|
||||
"id": "equipo-recien-instalado",
|
||||
"term": "Equipo recién instalado",
|
||||
"also": "fresh install",
|
||||
"def": "Host acabado de reinstalar desde cero, sin la <a href=\"#clave-cifrado\">clave de cifrado</a> local. Para restaurar copias cifradas hace falta primero recuperar la clave desde el <a href=\"#sobre-recuperacion\">sobre</a> almacenado en PBS, con la <a href=\"#passphrase-recuperacion\">passphrase de recuperación</a>."
|
||||
}
|
||||
]
|
||||
|
||||
@@ -10,23 +10,23 @@
|
||||
"header": {
|
||||
"title": "Cómo funciona",
|
||||
"description": "Desglose interno de una copia de seguridad creada con ProxMenux — sistema de ficheros, manifiesto e inventario de aplicaciones — y cómo la restauración consume los tres para reproducir el host de origen sobre un destino que puede no compartir el mismo kernel.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Un archivo, tres bloques",
|
||||
"body": "Cada copia produce un layout de directorio con tres bloques bien definidos bajo una única raíz de staging. El archivo que se sube al destino (archivo local <code>.tar.zst</code>, backup PBS o archivo Borg) contiene ese layout exacto. La restauración lee los tres bloques de forma independiente, en un orden concreto que garantiza la corrección: primero se copia el <strong>rootfs</strong> —el sistema de archivos raíz del host— para colocar la configuración, después se consulta <strong>el manifiesto</strong> para detectar drift y decidir qué omitir, y finalmente <strong>el inventario de aplicaciones</strong> dirige la pasada de reinstalación post-arranque. No hay dependencias entre bloques — cada uno puede inspeccionarse o extraerse de forma independiente."
|
||||
"body": "Cada copia produce una estructura con tres bloques definidos bajo un único directorio de preparación. El archivo subido al destino (<code>.tar.zst</code> local, copia PBS o archivo Borg) contiene esa misma estructura. La restauración utiliza los tres: consulta <strong>el manifiesto</strong> antes de aplicar cambios para detectar diferencias y decidir qué omitir; <strong>rootfs</strong> aporta los archivos de configuración, que se aplican en vivo o tras el reinicio; y <strong>el inventario de aplicaciones</strong> dirige la instalación de paquetes y la reinstalación de componentes después del arranque. Cada bloque puede inspeccionarse o extraerse de forma independiente."
|
||||
},
|
||||
"layout": {
|
||||
"heading": "Layout del archivo",
|
||||
"intro": "Cada archivo respeta el mismo layout con independencia del destino. El subdirectorio <code>metadata/</code> contiene los bloques estructurados; el subdirectorio <code>rootfs/</code> contiene la copia del sistema de ficheros.",
|
||||
"treeCaption": "El directorio de staging generado durante una copia. Todos los destinos reciben el mismo árbol (adaptado a su formato nativo: tar para local, chunks PBS para PBS, segmentos borg para Borg).",
|
||||
"tree": "backup-[timestamp]/\n├── manifest.json # estado estructurado del host\n├── metadata/\n│ ├── packages.manual.list # apt-mark showmanual\n│ ├── run_info.env # identidad de la ejecución + versión del kernel + método pmxcfs\n│ ├── paths_archived.txt # lista exacta de rutas que llegaron a rootfs/\n│ └── missing_paths.txt # rutas del perfil ausentes en el origen\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/systemd/network, /etc/ssh, …\n ├── root/ # /root (con subdirs volátiles excluidos)\n ├── usr/local/ # /usr/local/bin, /usr/local/share/proxmenux, …\n └── var/ # /var/lib/pve-cluster (config.db vía sqlite3 .backup), /var/spool/cron/…"
|
||||
"tree": "backup-[timestamp]/\n├── manifest.json # structured host state\n├── metadata/\n│ ├── packages.manual.list # apt-mark showmanual\n│ ├── run_info.env # backup run identity + kernel version + pmxcfs method\n│ ├── paths_archived.txt # exact list of paths that reached rootfs/\n│ └── missing_paths.txt # paths from the profile absent on source\n└── rootfs/\n ├── etc/ # /etc/pve, /etc/network, /etc/systemd/network, /etc/ssh, …\n ├── root/ # /root (with volatile subdirs excluded)\n ├── usr/local/ # /usr/local/bin, /usr/local/share/proxmenux, …\n └── var/ # /var/lib/pve-cluster (config.db via sqlite3 .backup), /var/spool/cron/…"
|
||||
},
|
||||
"rootfs": {
|
||||
"heading": "El bloque rootfs",
|
||||
"intro": "El árbol <code>rootfs/</code> es una <strong>copia plana del sistema de ficheros</strong> producida por <code>rsync</code> desde el host de origen. Contiene un <strong>perfil por defecto</strong> curado de rutas que importan para una restauración de Proxmox, más cualquier <strong>ruta personalizada</strong> añadida por el usuario al trabajo de copia o a la sesión interactiva. El conjunto es intencionadamente estrecho: solamente rutas que <em>contienen configuración</em> o <em>contienen estado que Proxmox no puede regenerar por sí solo</em>.",
|
||||
"defaultProfileTitle": "El perfil por defecto",
|
||||
"defaultProfileBody": "El perfil por defecto está definido por <code>hb_default_profile_paths</code> en <code>lib_host_backup_common.sh</code>. Cubre ocho categorías que en conjunto describen un host Proxmox operativo:",
|
||||
"defaultProfileBody": "El perfil por defecto se define en <code>hb_default_profile_paths</code> de <code>lib_host_backup_common.sh</code>. Incluye ocho categorías fijas y, si corresponde, el estado ZFS, que juntas describen un host Proxmox operativo:",
|
||||
"categoriesTitle": "Categorías de rutas",
|
||||
"categoryRows": [
|
||||
{
|
||||
@@ -121,11 +121,11 @@
|
||||
}
|
||||
],
|
||||
"schemaTitle": "Validación por esquema",
|
||||
"schemaBody": "ProxMenux incluye una plantilla que describe qué campos debe contener el manifiesto y qué forma tiene cada uno. Cuando se genera una copia se puede comprobar automáticamente que el manifiesto respeta esa plantilla, de modo que si un colector produjera un JSON malformado o con un campo mal escrito se detectaría en el momento. Es una comprobación destinada al desarrollo del propio ProxMenux: si el sistema no la tiene instalada, la copia sigue funcionando con normalidad y el manifiesto se genera igual."
|
||||
"schemaBody": "El manifiesto se valida con <code>scripts/backup_restore/schema/manifest.schema.json</code>. Ejecutar <code>build_manifest.sh --validate</code> activa una validación JSON Schema en Python (requiere <code>python3</code> y <code>jsonschema</code>). Si el módulo no está instalado, se omite la comprobación sin mostrar ningún aviso: esta validación es principalmente una ayuda para el desarrollo, no una dependencia necesaria durante la ejecución."
|
||||
},
|
||||
"applications": {
|
||||
"heading": "El inventario de aplicaciones",
|
||||
"intro": "Dos ficheros bajo <code>metadata/</code> catalogan todo lo instalado en el origen que no forma parte del conjunto de paquetes base de Proxmox VE. La restauración los utiliza para reproducir el conjunto exacto de software instalado por el usuario en el destino, usando APT o los instaladores propios de ProxMenux según cómo se instalara originalmente el software.",
|
||||
"intro": "Dos inventarios registran el software añadido al conjunto base de Proxmox VE: la lista de paquetes en <code>metadata/</code> y el registro de componentes dentro de rootfs, detallados a continuación. La restauración los usa para reproducir el software del usuario con APT o los instaladores de ProxMenux, según cómo se instalara originalmente.",
|
||||
"packagesTitle": "packages.manual.list",
|
||||
"packagesBody": "Una lista de texto plano producida por <code>apt-mark showmanual</code>: todos los paquetes APT que fueron <em>instalados explícitamente</em> en el host de origen, ordenados alfabéticamente. Esto excluye los paquetes instalados como dependencias del ISO base de Proxmox VE (que APT del destino vuelve a traer automáticamente). Es leída por <code>_rs_run_complete_extras</code> durante la restauración, filtrada por un filtro <em>cascade-safe</em> de tres pases (<code>dpkg -s</code> para lo ya instalado, detección de sibling-major para librerías, <code>apt-get install --simulate</code> para riesgo de cascade-remove) y después instalada con <code>apt-get install -y</code>.",
|
||||
"componentsTitle": "components_status.json (parte del rootfs)",
|
||||
|
||||
@@ -4,17 +4,17 @@
|
||||
"description": "ProxMenux Backup & Restore captura el estado completo de un host Proxmox — sistema de ficheros, manifiesto estructurado de configuración y paquetes/componentes instalados — y lo reproduce en el mismo host o en uno distinto. La copia y la restauración son autocontenidas: sin dependencias externas, y con soporte para restauraciones cross-kernel mediante un filtro direccional de subconjunto seguro y una hidratación kernel-agnóstica.",
|
||||
"ogTitle": "ProxMenux Backup & Restore — Descripción general",
|
||||
"ogDescription": "Copia y restauración completa del host Proxmox VE con manifiesto estructurado, lista de paquetes y reinstaladores de componentes.",
|
||||
"twitterTitle": "ProxMenux Backup & Restore | ProxMenux",
|
||||
"twitterTitle": "Copia de seguridad y restauración de ProxMenux | ProxMenux",
|
||||
"twitterDescription": "Copia y restauración completa del host Proxmox VE con manifiesto estructurado, lista de paquetes y reinstaladores de componentes."
|
||||
},
|
||||
"header": {
|
||||
"title": "Backup & Restore",
|
||||
"title": "Copias de seguridad y restauración",
|
||||
"description": "Copia y restauración a nivel de host para Proxmox VE. Captura el sistema de ficheros, la configuración y los componentes instalados en un único archivo y reproduce el host sobre la misma instalación de Proxmox o sobre una distinta, sin dependencias externas.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Qué es, en un párrafo",
|
||||
"body": "Una copia de ProxMenux captura el estado completo de un host Proxmox: <strong>el sistema de ficheros</strong> (directorios relevantes bajo <code>/etc</code>, <code>/root</code>, <code>/var/lib/pve-cluster</code>, más rutas personalizadas opcionales), <strong>un manifiesto estructurado</strong> (JSON con el hardware detectado, los parámetros del kernel, la topología de red, el estado de ZFS, los usuarios y las entradas de cron) y <strong>un inventario de aplicaciones</strong> (todos los paquetes marcados como instalados manualmente por APT, más la lista de componentes instalados por ProxMenux con sus versiones exactas). Cualquiera de los tres destinos soportados — archivo local, Proxmox Backup Server (recomendado) o Borg — recibe el mismo contenido autocontenido, y cualquiera de ellos puede hidratar el host de destino sin depender de que el origen esté accesible en el momento de la restauración."
|
||||
"body": "Una copia de ProxMenux recoge el estado completo de un host Proxmox: <strong>el sistema de archivos</strong> (los directorios pertinentes de <code>/etc</code>, <code>/root</code> y <code>/var/lib/pve-cluster</code>, además de las rutas personalizadas opcionales), <strong>un manifiesto estructurado</strong> (JSON con el hardware detectado, los parámetros del kernel, la configuración de red, el estado de ZFS, los usuarios y las entradas de cron) y <strong>un inventario de aplicaciones</strong> (los paquetes que APT marca como instalados manualmente y los componentes instalados por ProxMenux, con sus versiones exactas). Los tres destinos admitidos —archivo local, Proxmox Backup Server (recomendado) y Borg— reciben el mismo contenido autónomo. Cualquiera de ellos permite reconstruir el host de destino sin que el host de origen tenga que estar accesible durante la restauración."
|
||||
},
|
||||
"video": {
|
||||
"heading": "Vídeo demostración",
|
||||
@@ -24,23 +24,23 @@
|
||||
},
|
||||
"whatItIsNot": {
|
||||
"heading": "Qué no es",
|
||||
"intro": "La sección cubre copia y restauración <strong>a nivel de host</strong>: la instalación de Proxmox en sí, no las cargas de trabajo que se ejecutan sobre ella.",
|
||||
"intro": "Esta sección trata de la copia y restauración <strong>del host</strong>: la instalación de Proxmox, no las aplicaciones y máquinas que se ejecutan sobre ella.",
|
||||
"items": [
|
||||
"<strong>No es una herramienta de copia de VMs/CTs.</strong> Los discos de los invitados y su estado de RAM no se capturan en esta función; para eso está <code>vzdump</code>. Los <strong>ficheros de configuración</strong> de los invitados (<code>/etc/pve/nodes/<node>/qemu-server/*.conf</code> y <code>lxc/*.conf</code>) <strong>sí</strong> se capturan, de modo que tras la restauración el inventario de invitados reaparece y sus discos pueden re-adjuntarse desde una copia existente de PBS o local.",
|
||||
"<strong>No es una operación a nivel de clúster.</strong> Cada nodo se copia a sí mismo. La pertenencia al clúster se captura como parte de <code>/etc/pve</code> para que un nodo restaurado pueda re-incorporarse al clúster, pero restaurar un clúster completo requiere coordinación por nodo.",
|
||||
"<strong>No es una imagen completa del disco.</strong> Los binarios del kernel, el initramfs y la partición de arranque no se capturan. En la restauración, ProxMenux utiliza los artefactos de arranque propios del host de destino (regenerados automáticamente por <code>update-initramfs</code> y la herramienta de bootloader) e instala los controladores adecuados contra el kernel que el destino tenga en ejecución."
|
||||
"<strong>No es una herramienta de copia de VM/CT.</strong> Esta función no guarda los discos ni el estado de la RAM de los invitados; para eso está <code>vzdump</code>. Los <strong>archivos de configuración</strong> de los invitados (<code>/etc/pve/nodes/<node>/qemu-server/*.conf</code> y <code>lxc/*.conf</code>) <strong>sí</strong> se guardan. Tras restaurar, reaparece su inventario y los discos se pueden recuperar o volver a asociar a partir de una copia existente en PBS o en almacenamiento local.",
|
||||
"<strong>No es una operación sobre todo el clúster.</strong> Cada nodo guarda su propia copia. La pertenencia al clúster se incluye en <code>/etc/pve</code> para poder volver a incorporar un nodo restaurado, pero recuperar todo el clúster requiere coordinar la restauración de sus nodos.",
|
||||
"<strong>No es una imagen completa del disco.</strong> No se guardan los binarios del kernel, el initramfs ni la partición de arranque. Al restaurar, ProxMenux utiliza los archivos de arranque del host de destino, regenerados automáticamente con <code>update-initramfs</code> y la herramienta del gestor de arranque, e instala los controladores compatibles con el kernel que está ejecutando el destino."
|
||||
]
|
||||
},
|
||||
"threePillars": {
|
||||
"heading": "Los tres pilares de una copia",
|
||||
"intro": "Un archivo de ProxMenux se estructura en torno a tres cargas útiles autocontenidas. La restauración utiliza las tres en conjunto para reproducir el host de origen sobre un destino que puede no tener siquiera el mismo kernel instalado.",
|
||||
"diagramCaption": "Cada copia contiene los mismos tres bloques con independencia del destino. La restauración los consume todos: rootfs para colocar los ficheros, manifiesto para detectar drift y diferencias cross-kernel, e inventario de aplicaciones para reinstalar paquetes y componentes contra el kernel del propio destino.",
|
||||
"pillar1Label": "Sistema de ficheros",
|
||||
"pillar1Label": "Sistema de archivos",
|
||||
"pillar1Detail": "rootfs/\n(rsync de /etc,\n/etc/systemd/network,\n/root, más snapshot\nsqlite3 de\n/var/lib/pve-cluster,\n+ rutas opcionales)",
|
||||
"pillar2Label": "Manifiesto",
|
||||
"pillar2Detail": "manifest.json\n(hardware, params\ndel kernel, red,\nZFS, usuarios, cron,\npools ZFS, storage)",
|
||||
"pillar2Detail": "manifest.json\n(hardware, parámetros\ndel kernel, red,\nZFS, usuarios, cron,\npools ZFS, almacenamiento)",
|
||||
"pillar3Label": "Aplicaciones",
|
||||
"pillar3Detail": "packages.manual.list\n+ components_status.json\n(APT manual + instaladores\nProxMenux con versiones)"
|
||||
"pillar3Detail": "packages.manual.list\n+ components_status.json\n(paquetes APT manuales + instaladores\nProxMenux con versiones)"
|
||||
},
|
||||
"restoreIsUniversal": {
|
||||
"heading": "La restauración reproduce el host de origen, no el archivo",
|
||||
@@ -51,7 +51,7 @@
|
||||
"intro": "Cada paso del flujo de copia y restauración está disponible desde dos puntos de entrada. Ambos invocan la misma librería de shell, producen archivos idénticos y leen el mismo registro de trabajos.",
|
||||
"cliLabel": "ProxMenux Scripts (TUI)",
|
||||
"cliDetail": "menu → Utilities →\nHost Backup / Restore\n\nFlujo basado en diálogos,\namigable por SSH, admite\nejecución desatendida\ndesde scripts.",
|
||||
"webLabel": "ProxMenux Monitor (Web UI)",
|
||||
"webLabel": "ProxMenux Monitor (UI Web)",
|
||||
"webDetail": "Pestaña Backups en la\ninterfaz Web del Monitor.\n\nRestauración con un clic,\nlog en vivo, integrado con\nlas notificaciones y con\nel visor de rollback."
|
||||
},
|
||||
"whereNext": {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -10,7 +10,7 @@
|
||||
"header": {
|
||||
"title": "Trabajos programados",
|
||||
"description": "Trabajos de copia de host desatendidos. Dos modelos de creación: un trabajo nuevo e independiente con su propio horario, o un trabajo adjuntado a una tarea vzdump de PVE existente que hereda el horario y la retención de esa tarea. Ambos producen archivos idénticos al flujo interactivo.",
|
||||
"section": "Backup & Restore"
|
||||
"section": "Copias de seguridad y restauración"
|
||||
},
|
||||
"intro": {
|
||||
"title": "Los dos modelos de trabajo programado",
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"attachBadge": {
|
||||
"title": "Modo adjunto — recomendado cuando ya existe una tarea vzdump de PVE",
|
||||
"body": "Cuando ya hay una tarea de copia vzdump de PVE configurada para las VMs y los LXCs de este nodo, adjuntar la copia de host a esa tarea garantiza que la configuración del host se captura en la <strong>misma ventana</strong> que los invitados. En la restauración, las configuraciones de los invitados vienen de la copia de host (viven bajo <code>/etc/pve</code>), y los discos de los invitados vienen de la copia vzdump tomada al mismo tiempo — ambos conjuntos son consistentes entre sí, por lo que una recuperación completa del nodo puede reproducir el host y re-adjuntar cada invitado sin drift de versiones."
|
||||
"body": "Si ya existe una tarea vzdump de PVE para las VM y los LXC de este nodo, adjuntar la copia del host hace que se ejecute después de la copia de los invitados, en el <strong>mismo ciclo de copia</strong>. Al restaurar, las configuraciones de los invitados proceden de la copia del host (bajo <code>/etc/pve</code>) y sus discos de las copias vzdump de ese ciclo. Esto facilita coordinar la recuperación de todo el nodo, pero no es una instantánea atómica: los cambios durante el ciclo pueden dejar diferencias entre la configuración del host y el estado de los discos de los invitados."
|
||||
},
|
||||
"frequencyBadge": {
|
||||
"title": "Frecuencia recomendada",
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
"attachDetail": {
|
||||
"heading": "Cómo funciona el modo adjunto",
|
||||
"intro": "PVE escribe las tareas <code>vzdump</code> en <code>/etc/pve/jobs.cfg</code> — una entrada por tarea, cada una apuntando a un storage donde caen los dumps de VMs y LXCs. El modo adjunto requiere que ese storage sea un backend que ProxMenux entienda (Local o PBS); cuando la tarea dispara, ProxMenux se ejecuta al mismo tiempo.",
|
||||
"intro": "PVE guarda las tareas <code>vzdump</code> en <code>/etc/pve/jobs.cfg</code>: una sección por tarea, con el almacenamiento de las copias de VM y LXC. El modo adjunto requiere un backend compatible con ProxMenux (Local o PBS). La copia del host se ejecuta desde el hook job-end cuando termina la tarea de copia de los invitados.",
|
||||
"steps": [
|
||||
{
|
||||
"step": "1",
|
||||
@@ -59,14 +59,14 @@
|
||||
},
|
||||
{
|
||||
"step": "3",
|
||||
"detail": "<code>hb_install_vzdump_hook</code> registra un script-hook en <code>/etc/vzdump.conf</code>. Cuando PVE ejecuta cualquier tarea vzdump, el script-hook dispara; si el <code>$STOREID</code> que se le pasa coincide con el <code>PVE_STORAGE</code> de un trabajo adjuntado, el runner se invoca para ese trabajo."
|
||||
"detail": "<code>hb_install_vzdump_hook</code> registra un hook en <code>/etc/vzdump.conf</code>. En la fase job-end de cualquier tarea vzdump, compara el <code>$STOREID</code> recibido con el <code>PVE_STORAGE</code> de cada trabajo adjunto habilitado y ejecuta el script correspondiente si coincide. La asociación se basa en el almacenamiento, no en el ID de la tarea padre seleccionada."
|
||||
},
|
||||
{
|
||||
"step": "4",
|
||||
"detail": "El archivo aterriza en el mismo storage donde los dumps de vzdump acaban de escribirse: <code>path/dump/</code> para Local, o el repositorio PBS configurado en la entrada de storage de PVE."
|
||||
}
|
||||
],
|
||||
"outroBody": "El modo adjunto tiene una implicación operativa: desactivar o eliminar la tarea padre de PVE también desactiva la copia de host — no hay timer propio al que recurrir. La entrada del trabajo permanece en disco para poder re-adjuntarla más tarde."
|
||||
"outroBody": "El modo adjunto no tiene temporizador propio. Desactivar o eliminar la tarea padre seleccionada detiene ese disparador, pero otra tarea vzdump con el mismo almacenamiento aún puede activar la copia del host. Para impedirlo, desactiva o elimina el propio trabajo de ProxMenux. Al desactivarlo, su entrada sigue en disco para poder reactivarla o volver a adjuntarla."
|
||||
},
|
||||
"storageLayout": {
|
||||
"heading": "Ficheros que componen un trabajo",
|
||||
@@ -85,7 +85,7 @@
|
||||
"content": "Sólo modo Nuevo. El service invoca <code>run_scheduled_backup.sh JOB_ID</code>. El timer lo programa con <code>Persistent=true</code> (los disparos perdidos se ejecutan al siguiente arranque) y un pequeño <code>RandomizedDelaySec=120</code> para repartir carga cuando varios trabajos comparten la misma expresión OnCalendar."
|
||||
},
|
||||
{
|
||||
"path": "script-hook de /etc/vzdump.conf",
|
||||
"path": "/etc/vzdump.conf script-hook",
|
||||
"content": "Sólo modo adjunto. Lo instala una vez <code>hb_install_vzdump_hook</code>; casa el <code>PVE_STORAGE</code> de cada trabajo adjuntado contra el <code>$STOREID</code> que PVE pasa al script-hook."
|
||||
}
|
||||
]
|
||||
@@ -104,23 +104,23 @@
|
||||
"intro": "El menú del scheduler (TUI de Scripts) y la pestaña Backups del Monitor exponen las mismas acciones sobre cualquier trabajo.",
|
||||
"rows": [
|
||||
{
|
||||
"action": "Run now",
|
||||
"action": "Ejecutar ahora",
|
||||
"detail": "Invoca el runner de inmediato, saltándose el timer / hook de vzdump. Útil para verificar una configuración de trabajo sin esperar al siguiente disparo programado."
|
||||
},
|
||||
{
|
||||
"action": "Enable / Disable",
|
||||
"action": "Activar / Desactivar",
|
||||
"detail": "Modo Nuevo: <code>systemctl enable/disable --now</code> sobre el timer. Modo adjunto: cambia el flag <code>ENABLED</code> en el env del trabajo — el script-hook lo respeta en el siguiente disparo de PVE."
|
||||
},
|
||||
{
|
||||
"action": "Edit",
|
||||
"action": "Editar",
|
||||
"detail": "Reabre los prompts de destino, horario, perfil y retención y reescribe los ficheros del trabajo. Preserva el ID del trabajo."
|
||||
},
|
||||
{
|
||||
"action": "Delete",
|
||||
"action": "Eliminar",
|
||||
"detail": "Elimina el env del trabajo, el fichero de rutas, el timer + service systemd (modo Nuevo) y desactiva el binding del hook (modo adjunto). No toca los archivos ya presentes en el destino."
|
||||
},
|
||||
{
|
||||
"action": "View log",
|
||||
"action": "Ver log",
|
||||
"detail": "Muestra en streaming <code>/var/log/proxmenux/backup-jobs/JOB_ID-YYYYMMDD_HHMMSS.log</code> — un fichero de log por ejecución. El runner también emite una línea de estado compacta a journald bajo el service systemd."
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user