new beta 1.2.4.1

This commit is contained in:
MacRimi
2026-07-23 22:55:28 +02:00
parent 37f06b9e88
commit 91d503ea67
48 changed files with 1052 additions and 328 deletions

View File

@@ -113,6 +113,14 @@ export default async function TerminalTabPage({
{t.rich("target.body2", { strong, em, code, link: vmsLink })}
</p>
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("menuGuard.heading")}</h2>
<p className="mb-4 text-gray-800 leading-relaxed">
{t.rich("menuGuard.body1", { strong, em, code })}
</p>
<p className="mb-6 text-gray-800 leading-relaxed">
{t.rich("menuGuard.body2", { strong, em, code })}
</p>
<h2 className="text-2xl font-semibold mt-10 mb-4 text-gray-900">{t("fourTerminals.heading")}</h2>
<p className="mb-4 text-gray-800 leading-relaxed">{t("fourTerminals.intro")}</p>
<ul className="list-disc pl-6 mb-4 text-gray-800 leading-relaxed space-y-1">

View File

@@ -225,6 +225,14 @@ export default async function HealthMonitorPage({
{t("dashboardView.pillBody")}
</Callout>
<h3 className="text-lg font-semibold mt-6 mb-2 text-gray-900">{t("dashboardView.updateNowTitle")}</h3>
<p className="mb-4 text-gray-800 leading-relaxed">
{t.rich("dashboardView.updateNowBody1", { strong, em, code })}
</p>
<p className="mb-4 text-gray-800 leading-relaxed">
{t.rich("dashboardView.updateNowBody2", { strong, em, code })}
</p>
<h2 id="dismissing-alerts-and-the-suppression-duration" className="text-2xl font-semibold mt-10 mb-4 text-gray-900 scroll-mt-24">{t("dismiss.heading")}</h2>
<p className="mb-4 text-gray-800 leading-relaxed">
{t.rich("dismiss.intro", { em })}

View File

@@ -96,6 +96,11 @@ export default async function PostInstallNetworkPage({
{t.rich("sysctl.sourceOutro", { code })}
</p>
<h3 className="text-lg font-semibold mt-6 mb-2 text-gray-900">{t("sysctl.fwbrTitle")}</h3>
<p className="mb-4 text-gray-800 leading-relaxed">
{t.rich("sysctl.fwbrBody", { code })}
</p>
<Callout variant="warning" title={t("sysctl.rpFilterTitle")}>
{t.rich("sysctl.rpFilterBody", { em, code })}
</Callout>

View File

@@ -91,7 +91,6 @@ export default async function PostInstallStoragePage({
<thead className="bg-gray-100">
<tr>
<th className="border border-gray-200 px-3 py-2 text-left text-gray-900">{t("arc.headerRam")}</th>
<th className="border border-gray-200 px-3 py-2 text-left text-gray-900">{t("arc.headerMin")}</th>
<th className="border border-gray-200 px-3 py-2 text-left text-gray-900">{t("arc.headerMax")}</th>
</tr>
</thead>
@@ -99,7 +98,6 @@ export default async function PostInstallStoragePage({
{arcRows.map((row) => (
<tr key={row.ram}>
<td className="border border-gray-200 px-3 py-2">{row.ram}</td>
<td className="border border-gray-200 px-3 py-2">{row.min}</td>
<td className="border border-gray-200 px-3 py-2">{row.max}</td>
</tr>
))}

View File

@@ -1,7 +1,7 @@
{
"meta": {
"title": "Creating backups — interactive backup flow | ProxMenux",
"description": "The interactive backup flow in ProxMenux. Two entry points (Scripts TUI menu and Monitor Web UI), three destinations, two profile modes, one staging step, and one confirmation dialog. Documents the six-option matrix, the default and custom profiles, and what the operator sees between selecting a backup and the archive landing on the destination.",
"description": "The interactive backup flow in ProxMenux. Two entry points (Scripts TUI menu and Monitor Web UI), three destinations, two profile modes, one staging step, and one confirmation dialog. Documents the six-option matrix, the default and custom profiles, and what the user sees between selecting a backup and the archive landing on the destination.",
"ogTitle": "ProxMenux Backup — creating backups",
"ogDescription": "The interactive backup flow with three destinations, two profiles and a common staging step.",
"twitterTitle": "Creating backups | ProxMenux",
@@ -25,7 +25,7 @@
},
"modes": {
"heading": "Manual vs scheduled backups",
"body": "Backups can be produced in two modes: <strong>manual</strong> (the interactive flow this page documents — the operator picks a destination and a profile from a menu and watches the archive land) or <strong>scheduled</strong> (an unattended job that runs on a cron-style timer and applies the retention configured on the job). Both modes support the same three destinations and the same two profiles, and both are available from both entry points — the Scripts TUI menu and the Monitor Backups tab. Scheduled jobs use the same backend functions as the manual flow through <code>run_scheduled_backup.sh</code>; the archives produced are indistinguishable.",
"body": "Backups can be produced in two modes: <strong>manual</strong> (the interactive flow this page documents — the user picks a destination and a profile from a menu and watches the archive land) or <strong>scheduled</strong> (an unattended job that runs on a cron-style timer and applies the retention configured on the job). Both modes support the same three destinations and the same two profiles, and both are available from both entry points — the Scripts TUI menu and the Monitor Backups tab. Scheduled jobs use the same backend functions as the manual flow through <code>run_scheduled_backup.sh</code>; the archives produced are indistinguishable.",
"seeAlso": "The scheduled-jobs page covers the full flow, including how to create a job, attach it to an existing PVE vzdump timer, and configure the retention values.",
"monitorAlt": "ProxMenux Monitor Backups tab showing the New scheduled backup dialog with destination, profile, schedule and retention fields.",
"monitorCaption": "Scheduled backup — ProxMenux Monitor. The same wizard-style dialog that creates a manual backup carries the schedule and retention fields at the bottom for the unattended path."
@@ -37,7 +37,7 @@
{ "combo": "1", "destination": "PBS", "profile": "Default", "action": "Uploads the default profile plus persistent extras to a configured PBS repository." },
{ "combo": "2", "destination": "Borg", "profile": "Default", "action": "Creates an archive with the default profile plus persistent extras in the selected Borg repository." },
{ "combo": "3", "destination": "Local", "profile": "Default", "action": "Writes a <code>.tar.zst</code> archive with the default profile plus persistent extras to the configured local target." },
{ "combo": "4", "destination": "PBS", "profile": "Custom", "action": "Opens the path picker before the PBS upload; the operator ticks paths and can add new ones." },
{ "combo": "4", "destination": "PBS", "profile": "Custom", "action": "Opens the path picker before the PBS upload; the user ticks paths and can add new ones." },
{ "combo": "5", "destination": "Borg", "profile": "Custom", "action": "Opens the path picker before the Borg archive create." },
{ "combo": "6", "destination": "Local", "profile": "Custom", "action": "Opens the path picker before writing the local <code>.tar.zst</code>." }
]
@@ -45,11 +45,11 @@
"profiles": {
"heading": "Default vs Custom profile",
"defaultTitle": "Default profile",
"defaultBody": "The default profile is the curated list from <code>hb_default_profile_paths</code> (documented in <em>How it works</em> under <em>Path categories</em>) plus every entry in the persistent extras file <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code>. The operator confirms the destination and encryption options and the backup proceeds without further path selection.",
"defaultBody": "The default profile is the curated list from <code>hb_default_profile_paths</code> (documented in <em>How it works</em> under <em>Path categories</em>) plus every entry in the persistent extras file <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code>. The user confirms the destination and encryption options and the backup proceeds without further path selection.",
"customTitle": "Custom profile",
"customBody": "The custom profile opens a checklist showing every path in the default profile (unchecked) and every persistent extra (pre-checked, prefixed with <code>[+]</code>). The operator ticks the set for this run and can press <em>Add custom path</em> to append a new absolute path. Any path added inline is persisted to <code>backup-extra-paths.txt</code> so future backups pick it up automatically without re-adding it. Removing a persistent extra unticks it for this run but does not delete it from the file — deletion is a separate <em>Manage custom paths</em> action outside the backup flow.",
"customBody": "The custom profile opens a checklist showing every path in the default profile (unchecked) and every persistent extra (pre-checked, prefixed with <code>[+]</code>). The user ticks the set for this run and can press <em>Add custom path</em> to append a new absolute path. Any path added inline is persisted to <code>backup-extra-paths.txt</code> so future backups pick it up automatically without re-adding it. Removing a persistent extra unticks it for this run but does not delete it from the file — deletion is a separate <em>Manage custom paths</em> action outside the backup flow.",
"customPickerAlt": "Custom profile checklist showing the default-profile paths (unchecked) and persistent extras (pre-checked with a [+] prefix), plus buttons to add a new path or confirm the selection.",
"customPickerCaption": "Custom profile — the path picker. Default-profile paths are unchecked; persistent extras appear pre-checked with a [+] prefix. The operator ticks the set for this run.",
"customPickerCaption": "Custom profile — the path picker. Default-profile paths are unchecked; persistent extras appear pre-checked with a [+] prefix. The user ticks the set for this run.",
"manageCustomAlt": "Manage custom paths menu showing the list of persistent extras and options to add, remove or edit them.",
"manageCustomCaption": "Manage custom paths — the entry point where persistent extras are added or removed. Every path listed here is included automatically in Default-mode backups without needing to open the Custom picker."
},
@@ -57,11 +57,11 @@
"heading": "What runs regardless of destination",
"intro": "After the profile is resolved, every backend runs the same staging pipeline before diverging into its own upload path. <code>hb_prepare_staging</code> assembles the archive tree in <code>/tmp/proxmenux-DESTINATION-stage.XXXXXX</code> and populates each of the three payloads.",
"steps": [
{ "step": "1", "name": "rootfs assembly", "detail": "Runs <code>rsync -a</code> for each selected path into <code>staging_root/rootfs/</code>. Excludes volatile subpaths (bash history, caches, trash) from <code>/root/</code>. Paths absent from the source are recorded in <code>metadata/missing_paths.txt</code> without stopping the backup." },
{ "step": "1", "name": "rootfs assembly", "detail": "Runs <code>rsync -a</code> for each selected path into <code>staging_root/rootfs/</code>. The pmxcfs database at <code>/var/lib/pve-cluster/config.db</code> is captured separately via <code>sqlite3 .backup</code> to produce a consistent snapshot without stopping the cluster, and the <code>.db-wal</code> / <code>.db-shm</code> sidecars are excluded from the rsync; when <code>sqlite3</code> is not available a <code>config.db.raw-fallback</code> is dropped instead, and the restore promotes it on import. Volatile subpaths (bash history, caches, trash) are excluded from <code>/root/</code>. Paths absent from the source are recorded in <code>metadata/missing_paths.txt</code> without stopping the backup." },
{ "step": "2", "name": "Manifest generation", "detail": "<code>build_manifest.sh</code> orchestrates the six collectors and writes <code>manifest.json</code> at the top of staging. On collector failure, the affected section falls back to a documented empty default; the manifest is still valid." },
{ "step": "3", "name": "Package inventory", "detail": "<code>apt-mark showmanual</code> is captured verbatim into <code>metadata/packages.manual.list</code>. Component state is already inside the restored rootfs (<code>components_status.json</code>) because <code>/usr/local/share/proxmenux/</code> is part of the default profile." },
{ "step": "4", "name": "Run info", "detail": "<code>metadata/run_info.env</code> records the backup run identity — hostname, timestamp, kernel version — used by the restore's compatibility check to determine the cross-kernel direction." },
{ "step": "5", "name": "Notification (start)", "detail": "<code>hb_notify_lifecycle \"start\"</code> fires. If notifications are configured in the Monitor, an operator-facing <em>Host backup started</em> event is emitted. Silent if no channels are configured." }
{ "step": "5", "name": "Notification (start)", "detail": "<code>hb_notify_lifecycle \"start\"</code> fires. If notifications are configured in the Monitor, an user-facing <em>Host backup started</em> event is emitted. Silent if no channels are configured." }
]
},
"included": {
@@ -75,7 +75,7 @@
"<code>*.log</code> — log files."
],
"rootTitle": "<code>/root/</code> exclusions",
"rootBody": "<code>/root/</code> is part of the default profile so operator scripts and config land in the archive. Volatile subpaths are dropped:",
"rootBody": "<code>/root/</code> is part of the default profile so user scripts and config land in the archive. Volatile subpaths are dropped:",
"rootItems": [
"<code>.bash_history</code>",
"<code>.cache/</code>",
@@ -107,7 +107,7 @@
"archiveStructure": {
"heading": "Archive structure",
"intro": "The staging directory produced by every backend follows the same layout regardless of destination. The tarball, PBS <code>.pxar</code> or Borg archive stores this tree verbatim.",
"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\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/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, /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": "Confirmation summary",
@@ -115,7 +115,7 @@
},
"writing": {
"heading": "Writing to the destination",
"intro": "Once the operator confirms, each backend runs its own write step. The mechanics are covered in the destination pages; the shared surface is the log, the sidecar and the completion notification.",
"intro": "Once the user confirms, each backend runs its own write step. The mechanics are covered in the destination pages; the shared surface is the log, the sidecar and the completion notification.",
"rows": [
{ "topic": "Log file", "detail": "Every backend writes its full output to <code>/tmp/proxmenux-DESTINATION-backup-YYYYMMDD_HHMMSS.log</code> and, on failure, offers to open it in a scrollable dialog. The log path is printed in the completion summary only when the file has content." },
{ "topic": "Sidecar (local only)", "detail": "<code>hb_write_archive_sidecar</code> drops a <code>*.proxmenux.json</code> next to the local archive so the Monitor identifies it as a ProxMenux host backup even after moves or renames." },

View File

@@ -46,14 +46,14 @@
"intro": "The safe-subset filter alone would leave the target without the tuning the user had inside those boot-critical files: IOMMU cmdline for GPU passthrough, VFIO device IDs, custom <code>GRUB_TIMEOUT</code>, nvidia blacklists. The hydration pass re-applies those bits kernel-agnostically. Four phases run when the target kernel is newer than the backup's, each additive (never overwrites a value the target already carries) and idempotent (running twice is a no-op).",
"phaseRows": [
{ "phase": "1a — GRUB path", "detail": "For hosts using GRUB (ext4/lvm installs). <code>_rs_hyd_grub</code> merges every token from the backup's <code>manifest.kernel_params.cmdline_extra</code> into the target's live <code>GRUB_CMDLINE_LINUX_DEFAULT</code>, skipping tokens whose key the target already carries. Then merges whitelisted <code>GRUB_*</code> keys (<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>) from the backup's <code>/etc/default/grub</code> if they differ from the target's." },
{ "phase": "1b — systemd-boot / ZFS path", "detail": "For hosts using systemd-boot (typically ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> merges operator tokens from <code>cmdline_extra</code> into the target's <code>/etc/kernel/cmdline</code>, keeping the target's own <code>root=</code>, <code>boot=</code> and <code>rootflags=</code> boilerplate intact." },
{ "phase": "1b — systemd-boot / ZFS path", "detail": "For hosts using systemd-boot (typically ZFS-on-root). <code>_rs_hyd_kernel_cmdline</code> merges user tokens from <code>cmdline_extra</code> into the target's <code>/etc/kernel/cmdline</code>, keeping the target's own <code>root=</code>, <code>boot=</code> and <code>rootflags=</code> boilerplate intact." },
{ "phase": "2 — /etc/modules merge", "detail": "<code>_rs_hyd_modules</code> appends modules from <code>manifest.kernel_params.modules_loaded_at_boot</code> that are in the 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>) AND not already present in the target's <code>/etc/modules</code>." },
{ "phase": "3 — Whitelisted files copy", "detail": "<code>_rs_hyd_files</code> copies operator-authored files from the staging rootfs to the live target when the content differs. Whitelist covers VFIO/nvidia/blacklist files under <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, and the ProxMenux VFIO bind rule + nvidia udev rules under <code>/etc/udev/rules.d</code>. Distro-owned files (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) are intentionally excluded — their contents evolve between releases." },
{ "phase": "3 — Whitelisted files copy", "detail": "<code>_rs_hyd_files</code> copies user-authored files from the staging rootfs to the live target when the content differs. Whitelist covers VFIO/nvidia/blacklist files under <code>/etc/modprobe.d</code>, <code>/etc/modules-load.d</code>, and the ProxMenux VFIO bind rule + nvidia udev rules under <code>/etc/udev/rules.d</code>. Distro-owned files (<code>pve-blacklist.conf</code>, <code>mdadm.conf</code>, <code>nvme.conf</code>) are intentionally excluded — their contents evolve between releases." },
{ "phase": "4 — Force post-boot reflows", "detail": "The four phases write directly to the live target OUTSIDE the normal restore pipeline. To make the merged tokens/modules/files take effect on the next boot, <code>HB_HYDRATION_APPLIED=1</code> propagates through <code>plan.env</code> to <code>apply_pending_restore.sh</code>, which forces <code>NEEDS_INITRAMFS=1</code> and <code>NEEDS_GRUB=1</code> regardless of what was in the apply list. The post-boot dispatcher then regenerates initramfs and refreshes the bootloader." }
]
},
"planCommit": {
"heading": "Plan vs commit — the operator sees a preview first",
"heading": "Plan vs commit — the user sees a preview first",
"body": "The hydration runs in two modes. Before the confirmation dialog, ProxMenux runs <code>_rs_apply_bk_older_hydration</code> in <code>plan</code> mode: it computes exactly what would be merged, populates <code>RS_HYDRATION_SUMMARY</code> with a green block listing each action, and returns without writing. The confirmation dialog shows that green block alongside the amber safe-subset skip list, so the user sees UPFRONT what will be re-applied automatically. After the user confirms, ProxMenux re-runs the same helper in <code>commit</code> mode — same phases, same logic, but this time each phase writes to the live target. Cancelling the confirmation dialog leaves the target untouched."
},
"flowDiagram": {

View File

@@ -23,7 +23,7 @@
{
"id": "passphrase-recuperacion",
"term": "Recovery passphrase",
"def": "Text password the operator picks to protect the <a href=\"#sobre-recuperacion\">recovery envelope</a>. It is prompted twice with a match check, and is only used to encrypt the envelope and to decrypt it if the keyfile ever needs to be recovered. <strong>It is not the passphrase that unlocks the keyfile itself</strong>, and it is never sent to PBS. During a normal backup it never leaves the host."
"def": "Text password the user picks to protect the <a href=\"#sobre-recuperacion\">recovery envelope</a>. It is prompted twice with a match check, and is only used to encrypt the envelope and to decrypt it if the keyfile ever needs to be recovered. <strong>It is not the passphrase that unlocks the keyfile itself</strong>, and it is never sent to PBS. During a normal backup it never leaves the host."
},
{
"id": "clave-cifrado",
@@ -130,7 +130,7 @@
{
"id": "backup-id",
"term": "Backup ID",
"def": "Name of the <a href=\"#grupo-copia\">backup group</a>. ProxMenux defaults to <code>hostcfg-HOSTNAME</code> and lets the operator edit it before upload; unsupported characters are stripped automatically."
"def": "Name of the <a href=\"#grupo-copia\">backup group</a>. ProxMenux defaults to <code>hostcfg-HOSTNAME</code> and lets the user edit it before upload; unsupported characters are stripped automatically."
},
{
"id": "pxar",

View File

@@ -20,11 +20,11 @@
"heading": "Archive layout",
"intro": "Every archive follows the same tree layout regardless of destination. The <code>metadata/</code> subdirectory holds the structured payloads; the <code>rootfs/</code> subdirectory holds the filesystem copy.",
"treeCaption": "The staging directory laid out during a backup. Every destination receives the same tree (adapted to its native format: tar for local, PBS chunks for PBS, borg segments for Borg).",
"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\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/ssh, …\n ├── root/ # /root (with volatile subdirs excluded)\n ├── usr/local/ # /usr/local/bin, /usr/local/share/proxmenux, …\n └── var/ # /var/lib/pve-cluster, /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": "The rootfs payload",
"intro": "The <code>rootfs/</code> tree is a <strong>plain filesystem copy</strong> produced by <code>rsync</code> from the source host. It contains a curated <strong>default profile</strong> of paths that matter for a Proxmox restore, plus any <strong>custom paths</strong> added by the operator to the backup job or interactive session. The set is deliberately narrow: only paths that either <em>hold configuration</em> or <em>hold state that Proxmox cannot regenerate on its own</em>.",
"intro": "The <code>rootfs/</code> tree is a <strong>plain filesystem copy</strong> produced by <code>rsync</code> from the source host. It contains a curated <strong>default profile</strong> of paths that matter for a Proxmox restore, plus any <strong>custom paths</strong> added by the user to the backup job or interactive session. The set is deliberately narrow: only paths that either <em>hold configuration</em> or <em>hold state that Proxmox cannot regenerate on its own</em>.",
"defaultProfileTitle": "The default profile",
"defaultProfileBody": "The default profile is defined by <code>hb_default_profile_paths</code> in <code>lib_host_backup_common.sh</code>. It covers eight categories that together describe a working Proxmox host:",
"categoriesTitle": "Path categories",
@@ -32,17 +32,17 @@
{
"category": "PVE core",
"paths": "/etc/pve, /var/lib/pve-cluster, /etc/vzdump.conf",
"why": "Cluster filesystem contents, cluster live data, vzdump defaults."
"why": "Cluster filesystem contents and vzdump defaults. The pmxcfs database (<code>config.db</code>) is captured as a consistent snapshot via <code>sqlite3 .backup</code> without stopping the cluster, and the <code>.db-wal</code> / <code>.db-shm</code> sidecars are excluded from the rsync. When <code>sqlite3</code> is not available, a <code>config.db.raw-fallback</code> is dropped instead, which the restore promotes automatically."
},
{
"category": "Host identity & network",
"paths": "/etc/hostname, /etc/hosts, /etc/timezone, /etc/resolv.conf, /etc/network",
"why": "Everything the host needs to come up on the network with the same identity."
"paths": "/etc/hostname, /etc/hosts, /etc/timezone, /etc/resolv.conf, /etc/network, /etc/systemd/network",
"why": "Everything the host needs to come up on the network with the same identity. The <code>.link</code> files under <code>/etc/systemd/network</code> pin NIC names to their MAC, so reinstalls and hardware changes do not rename interfaces."
},
{
"category": "Access & auth",
"paths": "/etc/ssh, /etc/sudoers, /etc/sudoers.d, /etc/pam.d, /etc/security",
"why": "SSH keys, sudo rules and PAM configuration. Losing these locks the operator out of the restored host."
"why": "SSH keys, sudo rules and PAM configuration. Losing these locks the user out of the restored host."
},
{
"category": "Kernel & boot",
@@ -57,7 +57,7 @@
{
"category": "Packaging & cron",
"paths": "/etc/apt, /etc/cron.d, /etc/cron.{daily,hourly,weekly,monthly}, /etc/cron.allow, /etc/cron.deny, /var/spool/cron/crontabs",
"why": "APT sources for consistent package resolution, scheduled tasks defined by the operator."
"why": "APT sources for consistent package resolution, scheduled tasks defined by the user."
},
{
"category": "ProxMenux state & tools",
@@ -78,11 +78,11 @@
"customTitle": "Extending the profile with custom paths",
"customBody": "Beyond the default profile, ProxMenux offers two ways to include additional paths in a backup. They compose without conflict and both apply to interactive backups and scheduled jobs.",
"customExtrasTitle": "1. Persistent extras (per-host file)",
"customExtrasBody": "A text file at <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code> holds a list of absolute paths the operator has marked as \"always include\" on this host. When a backup runs in <strong>Default</strong> mode, ProxMenux appends these paths to the default profile automatically without asking. The file is edited from the interface — no manual editing needed — and persists across reboots and updates. One absolute path per line; <code>#</code> comments are allowed.",
"customExtrasBody": "A text file at <code>/usr/local/share/proxmenux/backup-extra-paths.txt</code> holds a list of absolute paths the user has marked as \"always include\" on this host. When a backup runs in <strong>Default</strong> mode, ProxMenux appends these paths to the default profile automatically without asking. The file is edited from the interface — no manual editing needed — and persists across reboots and updates. One absolute path per line; <code>#</code> comments are allowed.",
"customModeTitle": "2. Custom mode (per-run)",
"customModeBody": "Launching a backup in <strong>Custom</strong> mode replaces the automatic application of the default profile with a checklist showing every path: the default-profile entries and the persistent extras (prefixed with <code>[+]</code> and pre-checked). The operator ticks or unticks entries for that specific run, and can also press <em>Add custom path</em> to enter a new path — which is then persisted to the extras file for future backups.",
"customModeBody": "Launching a backup in <strong>Custom</strong> mode replaces the automatic application of the default profile with a checklist showing every path: the default-profile entries and the persistent extras (prefixed with <code>[+]</code> and pre-checked). The user ticks or unticks entries for that specific run, and can also press <em>Add custom path</em> to enter a new path — which is then persisted to the extras file for future backups.",
"customMissingTitle": "Paths absent from the source",
"customMissingBody": "Any path from the profile (default or added) that does not exist on the source host is recorded in <code>metadata/missing_paths.txt</code> inside the archive. The backup neither fails nor stops — the operator sees a summary of archived paths and missing paths at the end. In practice this happens for optional tooling paths like <code>/etc/wireguard</code> or <code>/etc/prometheus</code> when those tools are not installed."
"customMissingBody": "Any path from the profile (default or added) that does not exist on the source host is recorded in <code>metadata/missing_paths.txt</code> inside the archive. The backup neither fails nor stops — the user sees a summary of archived paths and missing paths at the end. In practice this happens for optional tooling paths like <code>/etc/wireguard</code> or <code>/etc/prometheus</code> when those tools are not installed."
},
"manifest": {
"heading": "The manifest payload",
@@ -102,7 +102,7 @@
{
"collector": "collect_storage.sh",
"produces": "storage_inventory",
"content": "ZFS pools (with pool type + member disks resolved to <code>/dev/disk/by-id/*</code> for portability), LVM volume groups + thin pools, physical disks with SMART capability, PVE <code>storage.cfg</code> entries, external mounts."
"content": "ZFS pools (with pool type + member disks resolved to <code>/dev/disk/by-id/*</code>, <code>/dev/disk/by-partuuid/*</code> or raw <code>/dev/sdX</code> paths depending on how each pool was originally created), LVM volume groups + thin pools, physical disks with SMART capability, PVE <code>storage.cfg</code> entries, external mounts."
},
{
"collector": "collect_kernel.sh",
@@ -157,8 +157,8 @@
},
"restoreFlow": {
"heading": "How the restore consumes the three payloads",
"intro": "The restore is a five-stage pipeline. Each stage reads a specific subset of the archive and updates the target host. No stage requires the source host to be reachable — the archive is fully self-contained.",
"stagesCaption": "Stage 1 uses the manifest to decide what to touch. Stage 2 copies rootfs paths that are safe to apply on a running system. Stage 3 stages the risky paths for the next boot. Stage 4 handles packages. Stage 5 runs after the reboot and reinstalls components against the target's kernel.",
"intro": "The restore is a six-stage pipeline. Each stage reads a specific subset of the archive and updates the target host. No stage requires the source host to be reachable — the archive is fully self-contained.",
"stagesCaption": "Stage 1 uses the manifest to decide what to touch. Stage 2 copies rootfs paths that are safe to apply on a running system. Stage 3 stages the risky paths for the next boot. Stage 3b imports non-root ZFS data pools whose disks are all present. Stage 4 handles packages. Stage 5 runs after the reboot and reinstalls components against the target's kernel.",
"stageRows": [
{
"stage": "1",
@@ -178,6 +178,12 @@
"reads": "rootfs/ (reboot + dangerous paths)",
"action": "<code>_rs_prepare_pending_restore</code> stages risky paths under <code>/var/lib/proxmenux/pending-restore/</code>, writes <code>plan.env</code>, <code>apply-on-boot.list</code> and <code>rs-skip-paths.txt</code>, and enables <code>proxmenux-restore-onboot.service</code> to fire on the next boot."
},
{
"stage": "3b",
"name": "Data-pool import",
"reads": "manifest.storage_inventory + target ZFS state",
"action": "<code>_rs_import_data_pools</code> imports every non-root ZFS pool whose full set of disks is present on the target. Pools carrying a foreign hostid are retried with <code>zpool import -f</code>. Pools missing any disk are skipped with a warning. The per-pool outcome is recorded in <code>/var/log/proxmenux/restore-datapools-&lt;timestamp&gt;.log</code>."
},
{
"stage": "4",
"name": "Package install",

View File

@@ -36,7 +36,7 @@
"intro": "A ProxMenux archive is structured around three self-contained payloads. The restore uses all three together to reproduce the source host on a target that may not even have the same kernel installed.",
"diagramCaption": "Every backup ships the same three payloads regardless of destination. The restore consumes all three: rootfs to lay down files, manifest to detect drift and cross-kernel differences, and application inventory to re-install packages and components against the target's own kernel.",
"pillar1Label": "Filesystem",
"pillar1Detail": "rootfs/\n(rsync of\n/etc, /root,\n/var/lib/pve-cluster,\n+ optional paths)",
"pillar1Detail": "rootfs/\n(rsync of /etc,\n/etc/systemd/network,\n/root, plus a\nsqlite3 snapshot\nof /var/lib/pve-cluster,\n+ optional paths)",
"pillar2Label": "Manifest",
"pillar2Detail": "manifest.json\n(hardware, kernel\nparams, network,\nZFS, users, cron,\nZFS pools, storage)",
"pillar3Label": "Applications",
@@ -44,7 +44,7 @@
},
"restoreIsUniversal": {
"heading": "The restore reproduces the source host, not the archive",
"body": "Restoring a ProxMenux backup does not just extract the filesystem. The restore flow reads the manifest to detect drift between the source and the target (hardware differences, NIC renames, kernel version, ZFS pool identity), replays the filesystem, then triggers the correct component installer for every service that was installed on the source (NVIDIA driver, Coral TPU, AMD GPU tools, Intel GPU tools). Each installer runs against the <strong>target's current kernel</strong>, so the restored host does not depend on the source's kernel being present. When the target's kernel is newer than the backup's, a kernel-agnostic <strong>hydration</strong> pass merges the operator's own tuning (IOMMU tokens, VFIO device IDs, custom quirks, GRUB keys) into the target's fresh boot configuration without copying kernel-tied files verbatim."
"body": "Restoring a ProxMenux backup does not just extract the filesystem. The restore flow reads the manifest to detect drift between the source and the target (hardware differences, NIC renames, kernel version, ZFS pool identity), replays the filesystem, then triggers the correct component installer for every service that was installed on the source (NVIDIA driver, Coral TPU, AMD GPU tools, Intel GPU tools). Each installer runs against the <strong>target's current kernel</strong>, so the restored host does not depend on the source's kernel being present. When the target's kernel is newer than the backup's, a kernel-agnostic <strong>hydration</strong> pass merges the user's own tuning (IOMMU tokens, VFIO device IDs, custom quirks, GRUB keys) into the target's fresh boot configuration without copying kernel-tied files verbatim."
},
"twoInterfaces": {
"heading": "Two interfaces, one backend",

File diff suppressed because one or more lines are too long

View File

@@ -39,7 +39,7 @@
"heading": "How attach mode works",
"intro": "PVE writes <code>vzdump</code> tasks to <code>/etc/pve/jobs.cfg</code> — one stanza per task, each pointing at a storage where the VM and LXC dumps land. Attach mode requires that storage to be a backend ProxMenux understands (Local or PBS); when the task fires, ProxMenux runs alongside it.",
"steps": [
{ "step": "1", "detail": "During job creation, ProxMenux lists compatible parent PVE tasks via <code>hb_pve_list_vzdump_jobs_for_backend</code>. The operator picks one." },
{ "step": "1", "detail": "During job creation, ProxMenux lists compatible parent PVE tasks via <code>hb_pve_list_vzdump_jobs_for_backend</code>. The user picks one." },
{ "step": "2", "detail": "The job's <code>.env</code> is written with <code>PVE_PARENT_JOB</code>, <code>PVE_STORAGE</code> and the inherited <code>KEEP_*</code> values; no systemd timer is created." },
{ "step": "3", "detail": "<code>hb_install_vzdump_hook</code> registers a script-hook in <code>/etc/vzdump.conf</code>. When PVE runs any vzdump task, the hook script fires; if the <code>$STOREID</code> passed to it matches an attached job's <code>PVE_STORAGE</code>, the runner is invoked for that job." },
{ "step": "4", "detail": "The archive lands in the same storage the vzdump dumps just wrote to: <code>path/dump/</code> for Local, or the PBS repository configured on the PVE storage entry." }
@@ -78,7 +78,7 @@
},
"notifications": {
"heading": "Notifications",
"body": "Every scheduled run fires the same <code>hb_notify_lifecycle</code> events as the interactive flow (<code>start</code>, <code>complete</code>, <code>fail</code>). If notification channels are configured in the Monitor, unattended jobs surface their results the same way manual backups do — an operator does not need to check the log to know whether a job succeeded."
"body": "Every scheduled run fires the same <code>hb_notify_lifecycle</code> events as the interactive flow (<code>start</code>, <code>complete</code>, <code>fail</code>). If notification channels are configured in the Monitor, unattended jobs surface their results the same way manual backups do — an user does not need to check the log to know whether a job succeeded."
},
"whereNext": {
"heading": "Where to go next",

View File

@@ -153,7 +153,7 @@
{
"href": "/docs/utils/system-update",
"label": "Proxmox System Update (interactive)",
"tail": " — wrapper that does all of this with a confirmation dialog and reboot prompt."
"tail": " — wrapper that does all of this with a confirmation dialog, an automatic DKMS rebuild of ProxMenux-managed drivers when a new kernel is installed, and a reboot prompt. Also launchable from the Update Now button of the ProxMenux Monitor dashboard."
},
{
"href": "/docs/utils/upgrade-pve8-pve9",

View File

@@ -57,7 +57,7 @@
},
"updating": {
"heading": "Updating",
"body": "ProxMenux self-updates. When a new version is available, you're prompted on the next <code>menu</code> launch and accepting replaces utility files and configurations in place. No manual download needed. Stable users get stable releases; beta users get beta releases (and the auto-switch prompt above when a stable cuts over)."
"body": "ProxMenux self-updates. When a new version is available, the next <code>menu</code> launch offers the update; accepting replaces utility files and configurations in place. No manual download needed. Stable users get stable releases; beta users get beta releases (and the auto-switch prompt above when a stable cuts over). The prompt shape depends on where <code>menu</code> runs: over SSH or the Proxmox console it is a classic yes / no dialog, and accepting applies the update immediately. Inside the WebSocket terminal of ProxMenux Monitor it is replaced by an informational msgbox — that terminal cannot survive a self-update mid-flight, so the msgbox shows the canonical one-line installer (<code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> for stable, or the equivalent <code>install_proxmenux_beta.sh</code> URL for beta) to run from SSH or console."
},
"uninstall": {
"heading": "Uninstalling",

View File

@@ -10,7 +10,7 @@
},
"intro": {
"title": "A real PTY in the browser",
"body": "The terminal allocates a server-side PTY through <code>flask_terminal_routes</code>, pipes it over a WebSocket to <code>xterm.js</code> in the browser, and runs as <code>root</code> (the systemd unit's user). Anything you can do in <code>ssh root@&lt;host&gt;</code> works here — including <code>vim</code>, <code>tmux</code>, ncurses tools and Proxmox CLIs (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>)."
"body": "The terminal allocates a server-side PTY through <code>flask_terminal_routes</code>, pipes it over a WebSocket to <code>xterm.js</code> in the browser, and runs as <code>root</code> (the systemd unit's user). Anything you can do in <code>ssh root@&lt;host&gt;</code> works here — including <code>vim</code>, <code>tmux</code>, ncurses tools and Proxmox CLIs (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Every PTY started from this tab exports the environment variable <code>PROXMENUX_TERMINAL=monitor</code>, which is inherited by every child <code>bash</code> process — including a subsequent <code>menu</code> launch — so ProxMenux flows can tell when they are running inside the Monitor's browser terminal."
},
"singleAlt": "ProxMenux Monitor Terminal tab — single terminal session showing Fastfetch system summary on login",
"singleCaption": "One host terminal open — the toolbar above shows the count (<em>1 / 4 terminals</em>), <em>+ New</em>, <em>Search</em>, <em>Clear</em> and <em>Close</em>. The mobile keyboard helpers appear under the terminal on touch devices.",
@@ -19,6 +19,11 @@
"body1": "The Terminal tab opens a shell on the <strong>Proxmox host itself</strong> — the same login you would get over SSH. Each tab opens a brand-new host terminal.",
"body2": "To reach an <strong>LXC container</strong> from the browser, use the dedicated <em>Console</em> button on every running CT card in the <link>VMs & LXCs tab</link>. It opens a modal that runs <code>pct enter &lt;vmid&gt;</code> and reuses the same mobile-friendly toolbar described below."
},
"menuGuard": {
"heading": "Self-update guard when menu runs inside this terminal",
"body1": "ProxMenux's <code>menu</code> self-updates in place: accepting the prompt replaces its own script tree and reloads. That works cleanly over SSH or the Proxmox console, but the browser terminal cannot survive it — the update tears down the very PTY the shell is running in, and the WebSocket drops mid-flight. To avoid stranding the session, the internal handlers <code>check_updates_stable</code>, <code>check_updates_beta</code> and <code>apply_release_channel</code> read <code>PROXMENUX_TERMINAL</code> and detect the Monitor context.",
"body2": "When they detect it, the classic yes / no dialog is replaced by an informational msgbox with the canonical one-line installer — <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> for stable, and the equivalent <code>install_proxmenux_beta.sh</code> URL for beta. The update itself is deferred to an SSH session or the Proxmox host console; the browser terminal is used only to acknowledge and read the command."
},
"fourTerminals": {
"heading": "Up to four terminals at once",
"intro": "The tab lets you open up to four host terminals simultaneously. Each one gets its own PTY and its own WebSocket — they are fully independent sessions. Two layouts switch with the icons next to the \"New\" button:",

View File

@@ -98,7 +98,7 @@
{
"category": "System Updates",
"checks": "Pending updates, security updates, kernel / PVE version, system age",
"events": "Security updates available; pinned kernel several minor versions behind; host uptime > 90 days."
"events": "Security updates available; pinned kernel several minor versions behind; host uptime > 90 days. When updates are pending, the Overview header shows an <em>Update Now</em> button that runs the full ProxMenux update flow inline; on close it re-hits the health endpoint with <code>?refresh=1</code> so the badge count reflects the new state without waiting for the next 5-min cycle."
},
{
"category": "Security & Certificates",
@@ -151,11 +151,14 @@
"<strong>Dismissed</strong> — items previously acknowledged by the user that are still inside their suppression window. Each row shows how much of the suppression remains and the configured duration. When the window expires, the item disappears from this list; if the underlying condition is still present and the category supports re-firing, it re-appears in <em>Active</em>."
],
"pillTitle": "The pill mirrors the worst category",
"pillBody": "The dashboard header colour is the highest severity across the ten categories: any CRITICAL → red, else any WARNING → yellow, else any INFO → blue, else green. The same logic drives the favicon dot and the PWA badge."
"pillBody": "The dashboard header colour is the highest severity across the ten categories: any CRITICAL → red, else any WARNING → yellow, else any INFO → blue, else green. The same logic drives the favicon dot and the PWA badge.",
"updateNowTitle": "Update Now button in the Overview header",
"updateNowBody1": "When the <em>System Updates</em> category reports one or more pending updates, the Overview header renders an <strong>Update Now</strong> button next to the health pill. The button opens a modal that runs the same host-side flow as <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em>: repo hygiene, <code>apt full-upgrade</code> via the safe worker <code>update-pve-safe.sh</code>, automatic DKMS rebuild of ProxMenux-managed drivers when a new kernel lands, autoremove / autoclean and a reboot prompt if the kernel changed. Progress lines stream in the modal as the worker prints them.",
"updateNowBody2": "When the run finishes, closing the modal calls <code>GET /api/health/details?refresh=1</code>, which invalidates the health-endpoint cache before serving. The pending-updates row and the pill severity are recomputed from the new package state on the spot, so the badge disappears without waiting for the next five-minute cycle. When the host is already up to date, the button is hidden — no visual noise on a healthy system."
},
"dismiss": {
"heading": "Dismissing alerts and the Suppression Duration",
"intro": "Some events are noisy by nature — a <em>System Updates: pending updates available</em> stays true until you patch the host, and you don't want a notification every five minutes for a week. The Health Monitor solves this with two coupled mechanisms:",
"intro": "Some events are noisy by nature — a <em>System Updates: pending updates available</em> stays true until you patch the host, and you don't want a notification every five minutes for a week. The <em>Update Now</em> button in the Overview header is the direct shortcut to resolve that specific case in place; for everything else, or when patching is deferred, the Health Monitor also offers two coupled silencing mechanisms:",
"step1": "<strong>Per-event Dismiss action</strong> in the modal. The Dismiss button opens a small dropdown with three options — <strong>24 hours</strong>, <strong>7 days</strong> or <strong>Permanently</strong> — letting you choose how long this specific alert stays silenced regardless of the category's default. Picking one calls <code>POST /api/health/acknowledge</code> with the <code>error_key</code> and the chosen <code>suppression_hours</code> (<code>-1</code> for permanent). The event moves to the Dismissed list with a timestamped <code>acknowledged_at</code>.",
"dropdownImageAlt": "Dismiss dropdown on a Health Monitor alert — 24 hours, 7 days or Permanently",
"dropdownImageCaption": "Per-event Dismiss dropdown. The chosen window applies to this single alert; if no per-event window is selected the category's default is used. Permanent dismisses are tagged with a distinct amber <em>Permanent</em> badge in the Dismissed list and never re-fire.",

View File

@@ -67,7 +67,7 @@
},
{
"tool": "Network stack tuning",
"what": "TCP buffer sizing, IPv4 hardening (redirects off, rp_filter=2, martian log off), local port range 1024-65535, TCP MTU probing, RFC 1337, plus a oneshot systemd unit to normalise virtual firewall bridges.",
"what": "TCP buffer sizing, IPv4 hardening (redirects off, rp_filter=2, martian log off), local port range 1024-65535, TCP MTU probing, RFC 1337, plus a helper at /usr/local/sbin/proxmenux-fwbr-tune wired to a oneshot systemd unit and a udev rule, so rp_filter=0 / log_martians=0 are re-applied to fwbr*/fwln*/fwpr*/tap* interfaces every time Proxmox recreates them at VM start/stop, reboot or live migration.",
"category": "Network",
"categorySlug": "network"
},
@@ -103,7 +103,7 @@
},
{
"tool": "Persistent interface names",
"what": "Writes /etc/systemd/network/10-*.link files matching each physical NIC by MAC so eth0 / enp… names stay stable across reboots and new NIC additions.",
"what": "Writes one /etc/systemd/network/10-proxmenux-<iface>.link per physical NIC (each starting with a 'Managed by ProxMenux' header) that pins the MAC to the current name, so eth0 / enp… names stay stable across reboots and new NIC additions.",
"category": "Network",
"categorySlug": "network"
}

View File

@@ -54,6 +54,8 @@
}
],
"sourceOutro": "It also adds <code>source /etc/network/interfaces.d/*</code> to <code>/etc/network/interfaces</code> if not already present — standard practice so you can drop modular interface snippets without editing the main file.",
"fwbrTitle": "Automatic tuning of virtual firewall bridges",
"fwbrBody": "Alongside the sysctl profile, ProxMenux installs a helper at <code>/usr/local/sbin/proxmenux-fwbr-tune</code> that applies <code>rp_filter=0</code> and <code>log_martians=0</code> to the <code>fwbr*</code> / <code>fwln*</code> / <code>fwpr*</code> / <code>tap*</code> interfaces Proxmox creates around VMs and containers. The helper is invoked by the <code>proxmenux-fwbr-tune.service</code> one-shot unit at boot, and by the <code>/etc/udev/rules.d/99-proxmenux-fwbr-tune.rules</code> rule on every <code>net add</code> event matching those prefixes — covering interfaces that Proxmox recreates on VM start/stop, reboot and live migration.",
"rpFilterTitle": "Why rp_filter=2 (loose) instead of 1 (strict)",
"rpFilterBody": "Strict reverse-path filtering drops packets whose source would be routed out a <em>different</em> interface. That's the right default on a client machine, but breaks badly on a Proxmox host where VM traffic often arrives on a bridge and leaves on an uplink with asymmetric routes. <code>rp_filter=2</code> (loose) only drops packets with truly unroutable sources. It's a pragmatic trade-off — slight reduction in local-IP-spoof detection in exchange for not breaking your VM network."
},
@@ -84,14 +86,14 @@
"LXC containers with <code>hotplug</code> NICs and bonded links can race on boot and end up named inconsistently. Pinning fixes that."
],
"writtenTitle": "What gets written",
"writtenIntro": "One file per physical NIC, at <code>/etc/systemd/network/10-&lt;iface&gt;.link</code>:",
"writtenOutro": "Any pre-existing <code>.link</code> files in that directory are copied to <code>/etc/systemd/network/backup-&lt;timestamp&gt;/</code> before touching anything.",
"writtenIntro": "One file per physical NIC, at <code>/etc/systemd/network/10-proxmenux-&lt;iface&gt;.link</code>. Each file starts with the header <code># Managed by ProxMenux — do not edit</code> so ProxMenux can distinguish its own files from user- or package-provided <code>.link</code> files.",
"writtenOutro": "<code>.link</code> files from other packages or hand-written by the user are left in place — only files carrying the ProxMenux header are managed. On re-run, the function reconciles its own set: it re-reads <code>MACAddress=</code> from every <code>10-proxmenux-*.link</code> and drops any whose MAC no longer appears under <code>/sys/class/net/</code>. Files written by an earlier ProxMenux release in the old <code>10-&lt;iface&gt;.link</code> format are migrated automatically the first time.",
"pveTitle": "PVE 9 vs PVE 8",
"pveBody": "On Proxmox VE 9 (<code>systemd-networkd</code> native), the script reloads udev rules after writing the <code>.link</code> files so new hotplug NICs pick up the correct name without a reboot. On PVE 8 (<code>ifupdown2</code>), interface naming is resolved at boot anyway — a reboot is required for the changes to take effect. The script sets the reboot flag either way so Customizable prompts you.",
"reviewTitle": "Review existing /etc/network/interfaces first",
"reviewBody": "If your host has legacy configuration in <code>/etc/network/interfaces</code> that references NIC names generated by the kernel's default scheme, pinning <em>today's</em> names is exactly what you want. But if you've already manually customised the config around specific names, double-check the pinning matches what the interfaces file expects before rebooting.",
"revertTitle": "Reversible from the Uninstall menu",
"revertBody": "<link>Uninstall Optimizations</link> deletes every <code>.link</code> file from <code>/etc/systemd/network/</code>, restoring the kernel's default naming on next reboot. The timestamped backup of the original files stays behind in case you need to restore specific ones manually."
"revertBody": "<link>Uninstall Optimizations</link> deletes only the <code>10-proxmenux-*.link</code> files carrying the ProxMenux header from <code>/etc/systemd/network/</code>. Any <code>.link</code> file added by the user or by another package is preserved. Interface names return to systemd's default behaviour on next reboot."
},
"related": {
"heading": "Related",

View File

@@ -145,10 +145,11 @@
"doesLabel": "What ProxMenux does:",
"doesItems": [
"Detects whether the root disk is SSD/NVMe by reading <code>/sys/block/&lt;dev&gt;/queue/rotational</code>. On a rotational disk the Automated flow asks first before installing.",
"Clones the upstream repository (<code>azlux/log2ram</code>) into <code>/tmp/log2ram</code> and runs its <code>install.sh</code>, then enables the <code>log2ram</code> systemd unit.",
"Clones the upstream repository (<code>azlux/log2ram</code>) into <code>/tmp/log2ram</code> and patches its <code>install.sh</code>, replacing <code>rsync -aAXv</code> with <code>rsync -aXv --no-acls</code>. That adjustment avoids the <em>set_acl: Operation not supported</em> exit 23 failure that the vanilla script triggers when moving /var/log on filesystems without ACL support. The <code>log2ram</code> systemd unit is enabled after install.",
"Sizes the ramdisk based on host RAM: <code>≤ 8 GB → 128M</code>, <code>≤ 16 GB → 256M</code>, <code>&gt; 16 GB → 512M</code>. Writes the value to <code>SIZE=</code> in <code>/etc/log2ram.conf</code>.",
"Schedules a periodic disk sync via <code>/etc/cron.d/log2ram</code>: every 1h / 3h / 6h according to the same RAM tier.",
"Installs an auto-sync guard at <code>/usr/local/bin/log2ram-check.sh</code>, wired to <code>/etc/cron.d/log2ram-auto-sync</code> to run every 10 minutes. When <code>/var/log</code> reaches 80% of the ramdisk size the guard vacuums journald; at 92% it also truncates <code>pveproxy access/error</code> and <code>pveam.log</code> before syncing — the plain <code>log2ram write</code> command copies tmpfs to disk but does NOT shrink the tmpfs, so this guard prevents PVE from crashing with <em>No space left on device</em> when logs grow uncontrolled.",
"Installs an auto-sync guard at <code>/usr/local/bin/log2ram-check.sh</code>, wired to <code>/etc/cron.d/log2ram-auto-sync</code> to run every 10 minutes. When <code>/var/log</code> reaches 80% of the ramdisk size the guard vacuums journald; at 92% it first runs <code>logrotate -f /etc/logrotate.d/proxmox-backup-api</code> when that file exists (forcing rotation of the PBS API logs, typically the largest consumer on a host running PBS) and then truncates <code>pveproxy access/error</code> and <code>pveam.log</code> before syncing. The plain <code>log2ram write</code> command copies tmpfs to disk but does NOT shrink the tmpfs, so this guard prevents PVE from crashing with <em>No space left on device</em> when logs grow uncontrolled.",
"Detects whether <code>proxmox-backup-server</code> runs as a service on the host. When present, drops <code>/etc/logrotate.d/proxmox-backup-api</code> (20 MB × 3 rotation) and <code>/etc/cron.hourly/proxmox-backup-logrotate</code>, so the PBS API logs — the usual source of growth on a PBS host — stay bounded even between Log2RAM's periodic syncs. On hosts without PBS this step is a no-op.",
"Adjusts systemd-journald limits (<code>SystemMaxUse</code>, <code>RuntimeMaxUse</code>) to fit within the ramdisk so a single burst cannot fill it.",
"Registers itself in <code>installed_tools.json</code> so it can be reverted from Uninstall Optimizations."
],

View File

@@ -18,30 +18,26 @@
"intro": "The <strong>Adaptive Replacement Cache (ARC)</strong> is ZFS's in-memory read cache. Without explicit tuning, ZFS happily grabs up to half the host RAM for itself, which is excessive on a Proxmox host that also needs memory for VMs and LXCs. This option caps ARC to a sane fraction of total RAM based on the size of the machine.",
"sizingTitle": "Sizing rules",
"headerRam": "Host RAM",
"headerMin": "ARC min",
"headerMax": "ARC max",
"headerMax": "ARC cap",
"rows": [
{
"ram": "≤ 16 GB",
"min": "512 MB",
"max": "512 MB"
"max": "512 MiB"
},
{
"ram": "17 32 GB",
"min": "1 GB",
"max": "1 GB"
"max": "1 GiB"
},
{
"ram": "> 32 GB",
"min": "RAM / 16",
"max": "RAM / 8"
"max": "RAM / 8 (floor 512 MiB)"
}
],
"after": "On a 64 GB host, that means 4 GB min / 8 GB max for ARC. The config is written to <code>/etc/modprobe.d/99-zfsarc.conf</code> and enables a few extra ZFS tunables (L2ARC prefetch on, L2ARC write max at 500 MB, longer TXG timeout).",
"after": "On a 64 GB host, that means an 8 GB cap for ARC. The file <code>/etc/modprobe.d/99-zfsarc.conf</code> contains a single directive — <code>options zfs zfs_arc_max=…</code>. Every other ZFS module parameter (<code>zfs_arc_min</code>, L2ARC prefetch/write throttle, TXG timeout) is left at its OpenZFS default. After writing the file, ProxMenux runs <code>update-initramfs -u -k all</code> and, when applicable, <code>proxmox-boot-tool refresh</code>, so the cap also lands in the initramfs used by ZFS-on-root setups.",
"rebootTitle": "Requires a reboot to take effect",
"rebootBody": "ARC settings are read when the <code>zfs</code> kernel module loads. They do <strong>not</strong> apply on a live system — you'll need to reboot the host for the cap to kick in. The script sets the \"reboot required\" flag automatically.",
"rebootBody": "ARC settings are read when the <code>zfs</code> kernel module loads. To make the cap take effect on ZFS-on-root hosts, ProxMenux regenerates the initramfs with <code>update-initramfs -u -k all</code> and, when applicable, refreshes the boot loader with <code>proxmox-boot-tool refresh</code>. A reboot is still required to pick up the new module parameter; the \"reboot required\" flag is set automatically.",
"safeTitle": "Safe on non-ZFS hosts",
"safeBody": "The function checks for the <code>zfs</code> command before touching anything. On ext4 / LVM-only Proxmox hosts, ticking this option is a no-op — nothing gets written.",
"safeBody": "The function only writes the config when <code>zpool list</code> reports at least one imported ZFS pool. On ext4 / LVM-only Proxmox hosts, or on machines with the ZFS tools installed but no pool imported, ticking this option is a no-op — nothing gets written.",
"verifyTitle": "Verification and manual rollback"
},
"autoSnap": {

View File

@@ -88,11 +88,11 @@
"items": [
{
"tool": "Network Optimizations",
"restores": "Removes /etc/sysctl.d/99-network.conf and the proxmenux-fwbr-tune.service unit. Reloads sysctl and systemd."
"restores": "Removes /etc/sysctl.d/99-network.conf together with the proxmenux-fwbr-tune.service unit, the /usr/local/sbin/proxmenux-fwbr-tune helper and the /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules udev rule. Reloads sysctl, systemd and the udev ruleset."
},
{
"tool": "Persistent Interface Names",
"restores": "Removes every .link file from /etc/systemd/network/. Interface names return to systemd's default behaviour on next reboot."
"restores": "Removes only the 10-proxmenux-*.link files carrying the ProxMenux header from /etc/systemd/network/. Any .link file provided by another package or written by the user is left in place. Interface names return to systemd's default behaviour on next reboot."
}
]
},
@@ -171,7 +171,7 @@
"packageTitle": "Package reinstall touches live Proxmox packages",
"packageBody": "Reverting <strong>Subscription Banner Removal</strong> reinstalls <code>pve-manager</code>, <code>proxmox-widget-toolkit</code>, <code>libjs-extjs</code> and <code>libpve-http-server-perl</code> with <code>--force-confnew</code>. This is generally safe but does touch the running web UI — refresh your browser afterwards, and expect a few seconds of reconnection. Don't run this in the middle of a migration or clone operation.",
"rebootTitle": "Persistent names and VFIO need a reboot",
"rebootBody": "Removing the <code>.link</code> files (<em>Persistent Interface Names</em>) and reverting <em>IOMMU/VFIO</em> do not affect the running system — they only matter after a reboot. ProxMenux sets the reboot flag automatically for these.",
"rebootBody": "Removing ProxMenux's <code>10-proxmenux-*.link</code> files (<em>Persistent Interface Names</em>) and reverting <em>IOMMU/VFIO</em> do not affect the running system — they only matter after a reboot. ProxMenux sets the reboot flag automatically for these.",
"perItemTitle": "You can revert one thing and keep the rest",
"perItemBody": "The uninstaller operates per-item. If you only want to remove Log2RAM but keep the network tuning and bashrc changes, tick only <em>Log2RAM</em>. Nothing else is touched, and the registry is updated accordingly."
},

View File

@@ -53,7 +53,8 @@
"Your existing config, ProxMenux Monitor login (<code>auth.json</code>), notification channels, post-install registry, custom thresholds — none of those are touched. The channel switch only swaps the script tree and the binary AppImage.",
"A Monitor that was active before the switch stays active after; one that was deactivated stays deactivated.",
"ProxMenux Monitor <code>auth.json</code>, API tokens and the JWT secret are preserved across channel changes. Sessions don't get logged out.",
"You can flip channels as many times as you like — the dialog will accept it every time and rerun the installer. No restart of Proxmox is required."
"You can flip channels as many times as you like — the dialog will accept it every time and rerun the installer. No restart of Proxmox is required.",
"The channel switch installer replaces ProxMenux's own script tree, so it cannot run inside the Monitor's browser terminal (that PTY would be torn down mid-update and leave the dialog stranded). If you launch the option from there, the confirmation is replaced by an informational msgbox showing the canonical one-line installer for the target channel; run that command from an SSH session or the Proxmox host console."
]
},
"feedback": {

View File

@@ -7,7 +7,7 @@
},
"header": {
"title": "Proxmox System Update",
"description": "Wrapper that detects the running Proxmox major version and delegates to the matching worker (PVE 8 or PVE 9). Repos are cleaned up, the no-subscription source is enabled, all packages are upgraded, conflicting packages are removed, and the system is cleaned up afterwards. A reboot prompt fires only when the kernel was actually updated.",
"description": "Wrapper that delegates to a single safe worker (<code>update-pve-safe.sh</code>) which detects the running Proxmox major version by itself. Repositories are cleaned up when they overlap with the base Proxmox / Debian sources, all packages are upgraded, ProxMenux-managed DKMS drivers are rebuilt if a new kernel landed, and the reboot prompt fires only when the kernel actually changed. Also launchable from the <em>Update Now</em> button in the ProxMenux Monitor dashboard header when pending updates are detected.",
"section": "Utilities"
},
"calloutWhat": {
@@ -22,15 +22,15 @@
},
"onTop": {
"heading": "What ProxMenux runs on top — verified against the script",
"intro": "This option runs <strong>exactly</strong> the apt command above, wrapped with the repo hygiene and post-upgrade cleanup the official upgrade guide also recommends. The list below maps 1:1 to <code>scripts/utilities/proxmox_update.sh</code> and the per-version worker scripts — nothing implied, every step is in the code:",
"intro": "This option runs <strong>exactly</strong> the apt command above, wrapped with the repo hygiene, DKMS rebuild for ProxMenux-managed drivers and post-upgrade cleanup the official upgrade guide also recommends. Everything below maps 1:1 to <code>scripts/utilities/proxmox_update.sh</code> and the single safe worker <code>scripts/global/update-pve-safe.sh</code> — nothing implied, every step is in the code:",
"items": [
"<strong>Detects the PVE major version</strong> (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>) and dispatches to <code>update-pve8.sh</code> or <code>update-pve9_2.sh</code> so the right codename and repo URLs are used.",
"<strong>Cleans up repositories</strong> before touching apt: disables the enterprise source (which 401s without a subscription), removes legacy repo files, and writes a clean no-subscription source for the host's codename.",
"<strong>Runs the upgrade non-interactively</strong> with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> — meaning if a configuration file you already modified also changed upstream, your version stays in place. No silent overwrites of custom configs.",
"<strong>Installs essential Proxmox packages</strong> if any are missing (<code>zfsutils-linux</code>, <code>proxmox-backup-restore-image</code>, <code>chrony</code>).",
"<strong>Detects the PVE major version</strong> from inside the worker (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>) and adapts the base Proxmox / Debian repo URLs (bookworm on PVE 8, trixie on PVE 9). There is no fan-out to per-version worker scripts — a single safe worker handles both.",
"<strong>Cleans up repositories in a conservative way.</strong> <code>ensure_repositories</code> runs first but only when the base Proxmox / Debian sources are missing — a bare host gets them written, a configured host is a no-op. <code>cleanup_duplicate_repos</code> then removes exact URL + Suite + Component duplicates only against <code>proxmox.sources</code> / <code>debian.sources</code>; user-authored files (enterprise, Ceph, alternative NTP mirrors, custom <code>download.proxmox.com/*</code> entries or hand-written <code>pve-*.list</code>) are left untouched, and every file is backed up before being edited.",
"<strong>Runs the upgrade non-interactively</strong> with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> — if a configuration file you already modified also changed upstream, your version stays in place. No silent overwrites of custom configs.",
"<strong>Skips forcing optional utilities.</strong> The safe worker does not push <code>zfsutils-linux</code>, <code>chrony</code>, <code>ifupdown2</code> or similar packages onto the host — a Proxmox install that opted out of any of them keeps its choice. Missing packages are surfaced by the higher-level installer flows, not by the update path.",
"<strong>LVM metadata sanity check</strong> against stray PV headers from passthrough disks (warn-only, no automatic fix).",
"<strong>Cleans up afterwards:</strong> <code>apt-get autoremove -y</code> + <code>apt-get autoclean -y</code>.",
"<strong>Reboot prompt</strong> only if the kernel actually changed (<code>/var/run/reboot-required</code> present or <code>linux-image</code> in the upgrade log)."
"<strong>DKMS rebuild before the reboot prompt.</strong> When the upgrade staged a new kernel, the wrapper calls <code>pmx_rebuild_dkms_after_kernel</code> to rebuild every driver that ProxMenux installed via DKMS against the incoming kernel version — so the modules are ready before the box comes back up. Reboot detection uses <code>/var/run/reboot-required</code> when <code>needrestart</code> is present, and falls back to a <code>dpkg-query</code> comparison between the running kernel and the newest installed <code>proxmox-kernel-*-pve-signed</code> / <code>pve-kernel-*-pve</code> package when it isn't — a signal that survives the many Proxmox hosts that ship without <code>needrestart</code>."
]
},
"calloutOneSentence": {
@@ -50,8 +50,8 @@
"detail": "pveversion |\ngrep -oP ''pve-manager/\\K[0-9]+''"
},
"bridge": {
"label": "Worker selection",
"detail": "PVE 8 → update-pve8.sh\nPVE 9 → update-pve9_2.sh"
"label": "Single safe worker",
"detail": "update-pve-safe.sh\n(detects PVE 8 / 9\ninternally)"
},
"target": {
"label": "Post-update",
@@ -61,13 +61,18 @@
},
"worker": {
"heading": "What the worker does",
"intro": "Both workers (<code>scripts/global/update-pve8.sh</code> for PVE 8 and <code>scripts/global/update-pve9_2.sh</code> for PVE 9) follow the same outline, with version-appropriate repo URLs and package names:",
"intro": "A single worker (<code>scripts/global/update-pve-safe.sh</code>) handles both PVE 8 and PVE 9. It detects the major version internally and uses the version-appropriate codename (<code>bookworm</code> or <code>trixie</code>) for its base sources. The stages are:",
"items": [
"<strong>Repo hygiene.</strong> Removes duplicate entries from <code>/etc/apt/sources.list</code> and <code>/etc/apt/sources.list.d/</code>. Comments out the enterprise repo if the host has no subscription and writes / enables the no-subscription source.",
"<strong>Apt update + full-upgrade.</strong> Pulls the latest package lists and applies all available upgrades for the current major version, running with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> so any configuration file you customised keeps its current contents when upstream also changed it.",
"<strong>Essential packages check.</strong> Installs <code>zfsutils-linux</code>, <code>chrony</code>, <code>ifupdown2</code> and a few others if the host is missing them.",
"<strong>LVM / storage sanity check.</strong> Repairs missing PV headers if detected.",
"<strong>Conflicting package removal.</strong> Drops packages known to clash on Proxmox (e.g. some time-sync daemons that fight chrony)."
"<strong>Sanity checks.</strong> Verifies at least ~1 GB free in <code>/var/cache/apt/archives</code> and pings <code>download.proxmox.com</code>. Aborts early with a clear message when either fails, so the run doesn't die in the middle of an apt transaction.",
"<strong>Repo bootstrap.</strong> <code>ensure_repositories</code> writes the base Proxmox / Debian sources only when they are missing (a fresh or hand-cleaned host); on a configured host it does nothing.",
"<strong>Apt update with GPG auto-recovery.</strong> On <code>NO_PUBKEY</code> for any repo (yours or a third-party one) the worker imports the missing key and retries automatically before failing.",
"<strong>Conservative duplicate cleanup.</strong> <code>cleanup_duplicate_repos</code> only removes exact URL + Suite + Component matches against <code>proxmox.sources</code> / <code>debian.sources</code>. User-authored files — enterprise, Ceph, alternative NTP mirrors, custom <code>download.proxmox.com/*</code> entries, hand-written <code>pve-*.list</code> — are left intact. Every file is backed up before modification.",
"<strong>Pending upgrades + security count.</strong> Reports how many packages will change and how many of those come from the security suite, so the confirmation dialog has real numbers to show.",
"<strong>Confirmation dialog.</strong> The wrapper asks for an explicit yes before touching apt.",
"<strong>apt full-upgrade.</strong> Runs with <code>DEBIAN_FRONTEND=noninteractive</code> and <code>--force-confdef --force-confold</code> so any configuration file you customised keeps its current contents when upstream also changed it. Never overwrites operator-edited configs silently.",
"<strong>LVM sanity check.</strong> <code>lvm_repair_check</code> refreshes VG metadata when disks passed through to guest VMs (DSM, TrueNAS, storage appliances) come back with old PV headers.",
"<strong>DKMS rebuild for ProxMenux-managed drivers.</strong> When the upgrade staged a new kernel, <code>pmx_rebuild_dkms_after_kernel</code> reads <code>components_status.json</code> for the drivers ProxMenux installed (currently <code>nvidia_driver</code> → module <code>nvidia</code>, <code>coral_driver</code> → module <code>gasket</code>), installs the matching kernel headers (<code>proxmox-headers-&lt;newkver&gt;</code> when available, else <code>pve-headers-&lt;newkver&gt;</code>) and runs <code>dkms autoinstall -k &lt;newkver&gt;</code>. If <code>dkms status</code> then doesn't show the modules built against the new kernel, the worker falls back to re-running each installer with <code>--auto-reinstall</code>. Any failure is logged but does not abort the update — you land on the reboot prompt in every case.",
"<strong>Post-cleanup.</strong> <code>apt-get autoremove</code> + <code>apt-get autoclean</code> before returning control to the wrapper."
]
},
"post": {
@@ -91,14 +96,14 @@
"body": "Running on an old kernel after upgrading <code>linux-image-*</code> means you're on a half-upgraded system: userspace is new, kernel is old. Most of the time things work, but ZFS modules, IOMMU groups, KSMBD and any out-of-tree drivers will only match the kernel they were built for — a mismatch produces obscure failures. Reboot at the earliest sensible moment."
},
"noSub": {
"heading": "When the no-subscription switch happens",
"intro": "Proxmox ships hosts with the enterprise repo enabled by default. Without a paid subscription, that repo returns 401 on <code>apt-get update</code>. The worker detects this and:",
"heading": "How the safe worker treats the enterprise repo",
"intro": "Proxmox ships hosts with the enterprise repo enabled by default. Without a paid subscription, that repo returns 401 on <code>apt-get update</code>. The safe worker deliberately does <strong>not</strong> touch enterprise or Ceph repositories — a host running with a real subscription must not have its config silently rewritten. What happens instead:",
"items": [
"Comments out (or disables) <code>/etc/apt/sources.list.d/pve-enterprise.list</code> (or the deb822 equivalent)",
"Writes <code>/etc/apt/sources.list.d/pve-no-subscription.list</code> (or the deb822 <code>proxmox.sources</code> for PVE 9) with the matching codename (<code>bookworm</code> for PVE 8, <code>trixie</code> for PVE 9)",
"Re-runs <code>apt-get update</code>"
"On a <strong>bare host</strong> with no base Proxmox / Debian sources at all, <code>ensure_repositories</code> writes the no-subscription source in the deb822 format (<code>proxmox.sources</code>) with the codename matching the detected major version (<code>bookworm</code> for PVE 8, <code>trixie</code> for PVE 9) and the matching Debian sources.",
"On a <strong>configured host</strong>, <code>ensure_repositories</code> is a no-op — whatever the operator chose (no-subscription, enterprise, or a mix) is preserved.",
"The enterprise <code>pve-enterprise.sources</code> / <code>ceph.sources</code> files are never modified by the update path. The removal of the enterprise repo when it's unwanted is handled elsewhere in ProxMenux (the Automated post-install script), not here."
],
"outro": "If you have a paid subscription, comment out the no-subscription source and uncomment the enterprise one before running this option."
"outro": "If you have a paid subscription, keep <code>pve-enterprise.sources</code> enabled and the safe worker will let it drive the upgrade unchanged. If you don't, either run the Automated post-install first (it does the switch and records it) or comment the enterprise source out manually — the update path will not do it for you."
},
"cluster": {
"heading": "Cluster considerations",
@@ -127,7 +132,7 @@
},
{
"title": "Kernel upgraded but the new modules are missing for an out-of-tree driver",
"body": "Out-of-tree modules (NVIDIA, ZFS via DKMS, custom NIC drivers) need to be rebuilt against the new kernel. Most are handled automatically by DKMS during the upgrade — confirm with <code>dkms status</code>. If something is missing: <code>dkms autoinstall</code>."
"body": "The drivers ProxMenux installed via DKMS (currently <code>nvidia_driver</code> and <code>coral_driver</code>) are rebuilt automatically at the end of the upgrade against the incoming kernel version, using <code>dkms autoinstall -k &lt;newkver&gt;</code> and, when needed, a fallback to each installer with <code>--auto-reinstall</code>. Confirm with <code>dkms status</code>. Third-party out-of-tree modules that aren't in ProxMenux's <code>components_status.json</code> registry (custom NIC drivers, hand-installed DKMS packages, …) still need a manual <code>dkms autoinstall</code> — the safe worker only touches what it originally installed."
},
{
"title": "The reboot prompt didn't appear but I'm sure the kernel changed",
@@ -137,7 +142,7 @@
},
"files": {
"heading": "Files involved",
"code": "scripts/utilities/proxmox_update.sh # this script (wrapper)\nscripts/global/update-pve8.sh # worker for PVE 8 hosts\nscripts/global/update-pve9_2.sh # worker for PVE 9 hosts\nscripts/global/common-functions.sh # cleanup_duplicate_repos used by workers\n/etc/apt/sources.list # may be edited\n/etc/apt/sources.list.d/* # may be edited / created\n/var/run/reboot-required # read to decide on reboot prompt\n/var/log/apt/history.log # read to detect kernel changes"
"code": "scripts/utilities/proxmox_update.sh # this script (wrapper)\nscripts/global/update-pve-safe.sh # single safe worker (PVE 8 + PVE 9)\nscripts/global/common-functions.sh # cleanup_duplicate_repos used by the worker\nscripts/global/utils-install-functions.sh # ensure_repositories + pmx_rebuild_dkms_after_kernel\n/usr/local/share/proxmenux/components_status.json # ProxMenux-managed DKMS driver registry\n/etc/apt/sources.list.d/proxmox.sources # deb822 no-subscription source (bare-host bootstrap)\n/etc/apt/sources.list.d/debian.sources # deb822 Debian sources (bare-host bootstrap)\n/var/run/reboot-required # read to decide on reboot prompt\n# Reboot fallback when needrestart isn't installed:\n# dpkg-query -W 'proxmox-kernel-*-pve-signed' 'pve-kernel-*-pve' vs. uname -r"
},
"related": {
"heading": "Related",

View File

@@ -98,7 +98,7 @@
{
"step": "1",
"name": "Ensamblado del rootfs",
"detail": "Ejecuta <code>rsync -a</code> por cada ruta seleccionada hacia <code>staging_root/rootfs/</code>. Excluye subrutas volátiles (historial de bash, cachés, papelera) de <code>/root/</code>. Las rutas ausentes en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
"detail": "Ejecuta <code>rsync -a</code> por cada ruta seleccionada hacia <code>staging_root/rootfs/</code>. La base pmxcfs en <code>/var/lib/pve-cluster/config.db</code> se captura aparte con <code>sqlite3 .backup</code> para obtener un snapshot consistente sin parar el clúster, y los sidecars <code>.db-wal</code> / <code>.db-shm</code> se excluyen del rsync; si <code>sqlite3</code> no está disponible, se deposita un <code>config.db.raw-fallback</code> que la restauración promociona al importar. Excluye subrutas volátiles (historial de bash, cachés, papelera) de <code>/root/</code>. Las rutas ausentes en el origen se registran en <code>metadata/missing_paths.txt</code> sin detener la copia."
},
{
"step": "2",
@@ -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\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/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, /var/spool/cron/crontabs"
"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"
},
"confirmation": {
"heading": "Resumen de confirmación",

View File

@@ -24,7 +24,7 @@
"id": "passphrase-recuperacion",
"term": "Passphrase de recuperación",
"also": "recovery passphrase",
"def": "Contraseña de texto que elige el operador 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."
"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",

View File

@@ -20,7 +20,7 @@
"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\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/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, /var/spool/cron/…"
"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/…"
},
"rootfs": {
"heading": "El bloque rootfs",
@@ -32,12 +32,12 @@
{
"category": "Núcleo PVE",
"paths": "/etc/pve, /var/lib/pve-cluster, /etc/vzdump.conf",
"why": "Contenido del filesystem del clúster, datos vivos del clúster, valores por defecto de vzdump."
"why": "Contenido del filesystem del clúster y valores por defecto de vzdump. La base pmxcfs (<code>config.db</code>) se captura con un snapshot consistente vía <code>sqlite3 .backup</code> sin parar el clúster, y los sidecars <code>.db-wal</code> y <code>.db-shm</code> quedan excluidos del rsync. Si <code>sqlite3</code> no está disponible, la copia deposita un <code>config.db.raw-fallback</code> que la restauración promociona automáticamente."
},
{
"category": "Identidad del host y red",
"paths": "/etc/hostname, /etc/hosts, /etc/timezone, /etc/resolv.conf, /etc/network",
"why": "Todo lo necesario para que el host arranque en red con la misma identidad."
"paths": "/etc/hostname, /etc/hosts, /etc/timezone, /etc/resolv.conf, /etc/network, /etc/systemd/network",
"why": "Todo lo necesario para que el host arranque en red con la misma identidad. Los ficheros <code>.link</code> bajo <code>/etc/systemd/network</code> pinnean los nombres de las NICs a su MAC, de modo que reinstalaciones y cambios de hardware no rebautizan las interfaces."
},
{
"category": "Acceso y autenticación",
@@ -102,7 +102,7 @@
{
"collector": "collect_storage.sh",
"produces": "storage_inventory",
"content": "Pools ZFS (con tipo de pool y discos miembro resueltos a <code>/dev/disk/by-id/*</code> para portabilidad), grupos de volúmenes LVM + thin pools, discos físicos con capacidad SMART, entradas de <code>storage.cfg</code> de PVE, puntos de montaje externos."
"content": "Pools ZFS (con tipo de pool y discos miembro resueltos a <code>/dev/disk/by-id/*</code>, <code>/dev/disk/by-partuuid/*</code> o rutas <code>/dev/sdX</code> en bruto según cómo se creara cada pool en el origen), grupos de volúmenes LVM + thin pools, discos físicos con capacidad SMART, entradas de <code>storage.cfg</code> de PVE, puntos de montaje externos."
},
{
"collector": "collect_kernel.sh",
@@ -157,8 +157,8 @@
},
"restoreFlow": {
"heading": "Cómo consume la restauración los tres bloques",
"intro": "La restauración es un pipeline de cinco etapas. Cada etapa lee un subconjunto concreto del archivo y actualiza el host de destino. Ninguna etapa requiere que el host de origen esté accesible — el archivo es totalmente autocontenido.",
"stagesCaption": "La etapa 1 usa el manifiesto para decidir qué tocar. La etapa 2 copia las rutas del rootfs seguras de aplicar en un sistema en ejecución. La etapa 3 deja las rutas de riesgo preparadas para el siguiente arranque. La etapa 4 gestiona los paquetes. La etapa 5 corre tras el reinicio y reinstala los componentes contra el kernel del destino.",
"intro": "La restauración es un pipeline de seis etapas. Cada etapa lee un subconjunto concreto del archivo y actualiza el host de destino. Ninguna etapa requiere que el host de origen esté accesible — el archivo es totalmente autocontenido.",
"stagesCaption": "La etapa 1 usa el manifiesto para decidir qué tocar. La etapa 2 copia las rutas del rootfs seguras de aplicar en un sistema en ejecución. La etapa 3 deja las rutas de riesgo preparadas para el siguiente arranque. La etapa 3b importa automáticamente los pools ZFS de datos cuyos discos están todos presentes. La etapa 4 gestiona los paquetes. La etapa 5 corre tras el reinicio y reinstala los componentes contra el kernel del destino.",
"stageRows": [
{
"stage": "1",
@@ -178,6 +178,12 @@
"reads": "rootfs/ (rutas reboot + dangerous)",
"action": "<code>_rs_prepare_pending_restore</code> deja las rutas de riesgo preparadas bajo <code>/var/lib/proxmenux/pending-restore/</code>, escribe <code>plan.env</code>, <code>apply-on-boot.list</code> y <code>rs-skip-paths.txt</code>, y habilita <code>proxmenux-restore-onboot.service</code> para que dispare en el siguiente arranque."
},
{
"stage": "3b",
"name": "Importación de pools de datos",
"reads": "manifest.storage_inventory + estado ZFS del destino",
"action": "<code>_rs_import_data_pools</code> intenta importar cada pool ZFS no-raíz cuyo conjunto completo de discos está presente en el destino. Los pools con hostid ajeno se reintentan con <code>zpool import -f</code>. Los pools con discos faltantes se saltan con una advertencia. El resultado por pool queda registrado en <code>/var/log/proxmenux/restore-datapools-&lt;timestamp&gt;.log</code>."
},
{
"stage": "4",
"name": "Instalación de paquetes",

View File

@@ -36,7 +36,7 @@
"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",
"pillar1Detail": "rootfs/\n(rsync de\n/etc, /root,\n/var/lib/pve-cluster,\n+ rutas opcionales)",
"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)",
"pillar3Label": "Aplicaciones",

File diff suppressed because one or more lines are too long

View File

@@ -153,7 +153,7 @@
{
"href": "/docs/utils/system-update",
"label": "Actualización del sistema Proxmox (interactivo)",
"tail": " — wrapper que hace todo esto con un diálogo de confirmación y preguntar antes de reiniciar."
"tail": " — wrapper que hace todo esto con un diálogo de confirmación, una recompilación DKMS automática de los drivers gestionados por ProxMenux cuando se instala un kernel nuevo y un prompt de reinicio. También lanzable desde el botón Update Now del dashboard de ProxMenux Monitor."
},
{
"href": "/docs/utils/upgrade-pve8-pve9",

View File

@@ -57,7 +57,7 @@
},
"updating": {
"heading": "Actualizar",
"body": "ProxMenux se autoactualiza. Cuando hay una nueva versión disponible, te lo pide en el siguiente lanzamiento de <code>menu</code> y aceptar reemplaza los archivos de utilidad y las configuraciones en sitio. No hace falta descarga manual. Los usuarios estables reciben releases estables; los usuarios beta reciben releases beta (y el prompt de auto-cambio de arriba cuando una estable se publica)."
"body": "ProxMenux se autoactualiza. Cuando hay una nueva versión disponible, el siguiente lanzamiento de <code>menu</code> ofrece la actualización; al aceptar se reemplazan los archivos de utilidad y las configuraciones en sitio. No hace falta descarga manual. Los usuarios estables reciben releases estables; los usuarios beta reciben releases beta (y el prompt de auto-cambio de arriba cuando una estable se publica). La forma del prompt depende de dónde se ejecute <code>menu</code>: por SSH o desde la consola de Proxmox aparece el diálogo clásico sí / no y al aceptar la actualización se aplica de inmediato. Dentro del terminal WebSocket de ProxMenux Monitor se sustituye por un msgbox informativo — ese terminal no puede sobrevivir a una autoactualización en curso, así que el msgbox muestra el instalador canónico de una línea (<code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para el canal estable, o la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta) para lanzarlo desde SSH o consola."
},
"uninstall": {
"heading": "Desinstalar",

View File

@@ -10,7 +10,7 @@
},
"intro": {
"title": "Un PTY real en el navegador",
"body": "El terminal asigna una PTY del lado del servidor a través de <code>flask_terminal_routes</code>, la canaliza por un WebSocket hacia <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code> (el usuario de la unidad systemd). Cualquier cosa que puedas hacer en <code>ssh root@&lt;host&gt;</code> funciona aquí — incluidos <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLIs de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>)."
"body": "El terminal asigna una PTY del lado del servidor a través de <code>flask_terminal_routes</code>, la canaliza por un WebSocket hacia <code>xterm.js</code> en el navegador y se ejecuta como <code>root</code> (el usuario de la unidad systemd). Cualquier cosa que puedas hacer en <code>ssh root@&lt;host&gt;</code> funciona aquí — incluidos <code>vim</code>, <code>tmux</code>, herramientas ncurses y las CLIs de Proxmox (<code>qm</code>, <code>pct</code>, <code>pvesh</code>, <code>pvecm</code>). Cada PTY lanzada desde esta pestaña exporta la variable de entorno <code>PROXMENUX_TERMINAL=monitor</code>, que hereda todo proceso <code>bash</code> hijo — incluida una llamada posterior a <code>menu</code> — para que los flujos de ProxMenux puedan saber si se están ejecutando dentro del terminal del navegador del Monitor."
},
"singleAlt": "Pestaña Terminal de ProxMenux Monitor — una única sesión de terminal mostrando el resumen del sistema de Fastfetch al hacer login",
"singleCaption": "Un terminal del host abierto — la barra de arriba muestra el recuento (<em>1 / 4 terminals</em>), <em>+ New</em>, <em>Search</em>, <em>Clear</em> y <em>Close</em>. Las ayudas de teclado para móvil aparecen bajo el terminal en dispositivos táctiles.",
@@ -19,6 +19,11 @@
"body1": "La pestaña Terminal abre una shell en el <strong>propio host Proxmox</strong> — el mismo login que obtendrías por SSH. Cada pestaña abre un terminal del host completamente nuevo.",
"body2": "Para llegar a un <strong>contenedor LXC</strong> desde el navegador, usa el botón <em>Console</em> dedicado en cada tarjeta de CT en ejecución de la <link>pestaña VMs y LXCs</link>. Abre una modal que ejecuta <code>pct enter &lt;vmid&gt;</code> y reutiliza la misma barra para móvil descrita abajo."
},
"menuGuard": {
"heading": "Guarda de autoactualización cuando menu corre dentro de este terminal",
"body1": "El <code>menu</code> de ProxMenux se autoactualiza en sitio: aceptar el prompt reemplaza su propio árbol de scripts y recarga. Eso funciona bien por SSH o desde la consola de Proxmox, pero el terminal del navegador no puede sobrevivir a ello — la actualización desmonta la propia PTY sobre la que corre la shell y el WebSocket cae a mitad. Para no dejar la sesión colgada, los handlers internos <code>check_updates_stable</code>, <code>check_updates_beta</code> y <code>apply_release_channel</code> leen <code>PROXMENUX_TERMINAL</code> y detectan el contexto Monitor.",
"body2": "Al detectarlo, el diálogo clásico sí / no se sustituye por un msgbox informativo con el instalador canónico de una línea — <code>bash -c \"$(wget -qLO - https://raw.githubusercontent.com/MacRimi/ProxMenux/main/install_proxmenux.sh)\"</code> para el canal estable, y la URL equivalente de <code>install_proxmenux_beta.sh</code> para beta. La actualización propiamente dicha se deja para una sesión SSH o la consola del host Proxmox; el terminal del navegador solo se usa para confirmar y leer el comando."
},
"fourTerminals": {
"heading": "Hasta cuatro terminales a la vez",
"intro": "La pestaña te permite abrir hasta cuatro terminales del host simultáneamente. Cada uno obtiene su propia PTY y su propio WebSocket — son sesiones totalmente independientes. Dos layouts se alternan con los iconos junto al botón \"New\":",

View File

@@ -98,7 +98,7 @@
{
"category": "Actualizaciones del sistema",
"checks": "Actualizaciones pendientes, actualizaciones de seguridad, kernel / versión de PVE, antigüedad del sistema",
"events": "Actualizaciones de seguridad disponibles; kernel pinneado varias versiones menores por detrás; uptime del host > 90 días."
"events": "Actualizaciones de seguridad disponibles; kernel pinneado varias versiones menores por detrás; uptime del host > 90 días. Cuando hay actualizaciones pendientes, la cabecera de Overview muestra un botón <em>Update Now</em> que ejecuta el flujo completo de actualización de ProxMenux en línea; al cerrar vuelve a golpear el endpoint de health con <code>?refresh=1</code> para que el badge refleje el nuevo estado sin esperar al siguiente ciclo de 5 minutos."
},
{
"category": "Seguridad y Certificados",
@@ -151,11 +151,14 @@
"<strong>Dismissed</strong> — items previamente reconocidos por el usuario que aún están dentro de su ventana de supresión. Cada fila muestra cuánto queda de la supresión y la duración configurada. Cuando la ventana caduca, el item desaparece de esta lista; si la condición subyacente sigue presente y la categoría soporta re-firing, reaparece en <em>Active</em>."
],
"pillTitle": "La pildora refleja la peor categoría",
"pillBody": "El color de la cabecera del panel es la severidad más alta entre las diez categorías: cualquier CRITICAL → rojo, si no cualquier WARNING → amarillo, si no cualquier INFO → azul, si no verde. La misma lógica dirige el punto del favicon y el badge del PWA."
"pillBody": "El color de la cabecera del panel es la severidad más alta entre las diez categorías: cualquier CRITICAL → rojo, si no cualquier WARNING → amarillo, si no cualquier INFO → azul, si no verde. La misma lógica dirige el punto del favicon y el badge del PWA.",
"updateNowTitle": "Botón Update Now en la cabecera de Overview",
"updateNowBody1": "Cuando la categoría <em>Actualizaciones del sistema</em> reporta una o más actualizaciones pendientes, la cabecera de Overview renderiza un botón <strong>Update Now</strong> al lado de la pildora de salud. El botón abre una modal que ejecuta el mismo flujo del lado del host que <em>ProxMenux → Settings post-install Proxmox → Proxmox System Update</em>: higiene de repos, <code>apt full-upgrade</code> vía el worker seguro <code>update-pve-safe.sh</code>, recompilación DKMS automática de los drivers gestionados por ProxMenux cuando aterriza un kernel nuevo, autoremove / autoclean y prompt de reinicio si el kernel cambió. Las líneas de progreso van llegando a la modal según las va imprimiendo el worker.",
"updateNowBody2": "Al terminar la ejecución, cerrar la modal llama a <code>GET /api/health/details?refresh=1</code>, que invalida la caché del endpoint de health antes de servir. La fila de actualizaciones pendientes y la severidad de la pildora se recomputan al momento a partir del nuevo estado de paquetes, así que el badge desaparece sin esperar al siguiente ciclo de cinco minutos. Cuando el host ya está al día el botón queda oculto — sin ruido visual en un sistema sano."
},
"dismiss": {
"heading": "Hacer dismiss de alertas y la Suppression Duration",
"intro": "Algunos eventos son ruidosos por naturaleza — un <em>System Updates: actualizaciones pendientes disponibles</em> permanece cierto hasta que parches el host, y no quieres una notificación cada cinco minutos durante una semana. El Monitor de salud resuelve esto con dos mecanismos acoplados:",
"intro": "Algunos eventos son ruidosos por naturaleza — un <em>System Updates: actualizaciones pendientes disponibles</em> permanece cierto hasta que parches el host, y no quieres una notificación cada cinco minutos durante una semana. El botón <em>Update Now</em> de la cabecera de Overview es el atajo directo para resolver ese caso concreto en sitio; para todo lo demás, o cuando el parche se aplaza, el Monitor de salud ofrece además dos mecanismos de silenciamiento acoplados:",
"step1": "<strong>Acción Dismiss por evento</strong> en el modal. El botón Dismiss abre un dropdown con tres opciones — <strong>24 horas</strong>, <strong>7 días</strong> o <strong>Permanently</strong> — que te permite elegir cuánto tiempo se silencia esta alerta concreta independientemente del valor por defecto de la categoría. Elegir una llama a <code>POST /api/health/acknowledge</code> con el <code>error_key</code> y el <code>suppression_hours</code> escogido (<code>-1</code> para permanente). El evento se mueve a la lista Dismissed con un <code>acknowledged_at</code> con timestamp.",
"dropdownImageAlt": "Dropdown de Dismiss sobre una alerta del Monitor de salud — 24 horas, 7 días o Permanently",
"dropdownImageCaption": "Dropdown Dismiss por evento. La ventana elegida aplica solo a esta alerta; si no eliges ninguna por evento se usa el valor por defecto de la categoría. Los dismisses permanentes se marcan con un badge ámbar distinto <em>Permanent</em> en la lista Dismissed y no se re-disparan.",

View File

@@ -67,7 +67,7 @@
},
{
"tool": "Tuning del stack de red",
"what": "Dimensionado de buffers TCP, hardening IPv4 (redirects off, rp_filter=2, martian log off), rango de puertos locales 1024-65535, TCP MTU probing, RFC 1337, más una unit systemd oneshot para normalizar los bridges de firewall virtual.",
"what": "Dimensionado de buffers TCP, hardening IPv4 (redirects off, rp_filter=2, martian log off), rango de puertos locales 1024-65535, TCP MTU probing, RFC 1337, más un helper en /usr/local/sbin/proxmenux-fwbr-tune conectado a una unit systemd oneshot y a una regla udev, de forma que rp_filter=0 / log_martians=0 se reapliquen a las interfaces fwbr*/fwln*/fwpr*/tap* cada vez que Proxmox las recrea al iniciar/parar VMs, en reinicios o en migraciones en vivo.",
"category": "Network",
"categorySlug": "network"
},
@@ -103,7 +103,7 @@
},
{
"tool": "Nombres de interfaz persistentes",
"what": "Escribe archivos /etc/systemd/network/10-*.link que emparejan cada NIC física por MAC para que los nombres eth0 / enp… se mantengan estables tras reinicios y al añadir nuevas NICs.",
"what": "Escribe un /etc/systemd/network/10-proxmenux-<iface>.link por NIC física (cada uno comenzando con la cabecera 'Managed by ProxMenux') que fija el MAC al nombre actual, de forma que los nombres eth0 / enp… se mantengan estables tras reinicios y al añadir nuevas NICs.",
"category": "Network",
"categorySlug": "network"
}

View File

@@ -54,6 +54,8 @@
}
],
"sourceOutro": "También añade <code>source /etc/network/interfaces.d/*</code> a <code>/etc/network/interfaces</code> si no está ya presente — práctica estándar para que puedas dejar snippets modulares de interfaz sin editar el archivo principal.",
"fwbrTitle": "Ajuste automático de los bridges de firewall virtual",
"fwbrBody": "Junto al perfil sysctl, ProxMenux instala un helper en <code>/usr/local/sbin/proxmenux-fwbr-tune</code> que aplica <code>rp_filter=0</code> y <code>log_martians=0</code> a las interfaces <code>fwbr*</code> / <code>fwln*</code> / <code>fwpr*</code> / <code>tap*</code> que Proxmox crea alrededor de VMs y contenedores. El helper lo lanza la unit oneshot <code>proxmenux-fwbr-tune.service</code> al arranque y la regla <code>/etc/udev/rules.d/99-proxmenux-fwbr-tune.rules</code> en cada evento <code>net add</code> que coincida con esos prefijos — cubriendo las interfaces que Proxmox recrea al iniciar/parar VMs, en reinicios y en migraciones en vivo.",
"rpFilterTitle": "Por qué rp_filter=2 (loose) en lugar de 1 (strict)",
"rpFilterBody": "El reverse-path filtering strict descarta paquetes cuya fuente se rutearía por una interfaz <em>distinta</em>. Es el valor por defecto correcto en una máquina cliente, pero rompe gravemente en un host Proxmox donde el tráfico de VMs a menudo llega por un bridge y sale por un uplink con rutas asimétricas. <code>rp_filter=2</code> (loose) solo descarta paquetes con fuentes verdaderamente no enrutables. Es un trade-off pragmático — ligera reducción en la detección de spoofing de IP local a cambio de no romper tu red de VMs."
},
@@ -84,14 +86,14 @@
"Contenedores LXC con NICs <code>hotplug</code> y enlaces bonded pueden hacer race en el arranque y acabar nombrados de forma inconsistente. Fijarlos lo soluciona."
],
"writtenTitle": "Qué se escribe",
"writtenIntro": "Un archivo por NIC física, en <code>/etc/systemd/network/10-&lt;iface&gt;.link</code>:",
"writtenOutro": "Cualquier archivo <code>.link</code> preexistente en ese directorio se copia a <code>/etc/systemd/network/backup-&lt;timestamp&gt;/</code> antes de tocar nada.",
"writtenIntro": "Un archivo por NIC física, en <code>/etc/systemd/network/10-proxmenux-&lt;iface&gt;.link</code>. Cada archivo comienza con la cabecera <code># Managed by ProxMenux — do not edit</code>, marca que permite a ProxMenux distinguir sus propios archivos de los <code>.link</code> provistos por el usuario o por otros paquetes.",
"writtenOutro": "Los archivos <code>.link</code> de otros paquetes o escritos a mano por el usuario se dejan intactos — solo se gestionan los archivos que llevan la cabecera de ProxMenux. En cada nueva ejecución la función reconcilia su propio conjunto: relee <code>MACAddress=</code> de cada <code>10-proxmenux-*.link</code> y elimina los cuya MAC ya no aparece en <code>/sys/class/net/</code>. Los archivos escritos por una versión antigua de ProxMenux en el formato <code>10-&lt;iface&gt;.link</code> se migran automáticamente en la primera ejecución.",
"pveTitle": "PVE 9 vs PVE 8",
"pveBody": "En Proxmox VE 9 (<code>systemd-networkd</code> nativo), el script recarga las reglas udev tras escribir los archivos <code>.link</code> para que las nuevas NICs hotplug cojan el nombre correcto sin reiniciar. En PVE 8 (<code>ifupdown2</code>), el naming de interfaz se resuelve en el arranque de todos modos — se requiere un reinicio para que los cambios surtan efecto. El script activa el flag de reinicio en cualquier caso para que Personalizable te lo pregunte.",
"reviewTitle": "Revisa antes el /etc/network/interfaces existente",
"reviewBody": "Si tu host tiene configuración legacy en <code>/etc/network/interfaces</code> que referencia nombres de NIC generados por el esquema por defecto del kernel, fijar los nombres <em>de hoy</em> es exactamente lo que quieres. Pero si ya has customizado manualmente la configuración alrededor de nombres específicos, comprueba dos veces que el pinning coincide con lo que el archivo interfaces espera antes de reiniciar.",
"revertTitle": "Reversible desde el menú Uninstall",
"revertBody": "<link>Uninstall Optimizations</link> borra cada archivo <code>.link</code> de <code>/etc/systemd/network/</code>, restaurando el naming por defecto del kernel en el siguiente reinicio. El backup con marca de tiempo de los archivos originales se queda por si necesitas restaurar alguno manualmente."
"revertBody": "<link>Uninstall Optimizations</link> solo borra los archivos <code>10-proxmenux-*.link</code> que llevan la cabecera de ProxMenux en <code>/etc/systemd/network/</code>. Cualquier archivo <code>.link</code> añadido por el usuario o por otro paquete se preserva. Los nombres de interfaz vuelven al comportamiento por defecto de systemd en el siguiente reinicio."
},
"related": {
"heading": "Relacionado",

View File

@@ -145,10 +145,11 @@
"doesLabel": "Qué hace ProxMenux:",
"doesItems": [
"Detecta si el disco raíz es SSD/NVMe leyendo <code>/sys/block/&lt;dev&gt;/queue/rotational</code>. En un disco rotacional el flujo Automatizado pregunta antes de instalar.",
"Clona el repositorio oficial (<code>azlux/log2ram</code>) en <code>/tmp/log2ram</code> y ejecuta su <code>install.sh</code>, luego habilita la unit systemd <code>log2ram</code>.",
"Clona el repositorio oficial (<code>azlux/log2ram</code>) en <code>/tmp/log2ram</code> y aplica un patch a su <code>install.sh</code>, sustituyendo <code>rsync -aAXv</code> por <code>rsync -aXv --no-acls</code>. Ese ajuste evita el fallo <em>set_acl: Operation not supported</em> con exit 23 que el script vanilla produce al mover /var/log en sistemas de archivos sin soporte de ACLs. La unit systemd <code>log2ram</code> se habilita después de la instalación.",
"Dimensiona la ramdisk según la RAM del host: <code>≤ 8 GB → 128M</code>, <code>≤ 16 GB → 256M</code>, <code>&gt; 16 GB → 512M</code>. Escribe el valor en <code>SIZE=</code> de <code>/etc/log2ram.conf</code>.",
"Programa una sincronización periódica a disco vía <code>/etc/cron.d/log2ram</code>: cada 1h / 3h / 6h según el mismo tramo de RAM.",
"Instala un guardián de auto-sync en <code>/usr/local/bin/log2ram-check.sh</code>, conectado a <code>/etc/cron.d/log2ram-auto-sync</code> para ejecutarse cada 10 minutos. Cuando <code>/var/log</code> alcanza el 80% del tamaño de la ramdisk el guardián compacta journald; al 92% además trunca <code>pveproxy access/error</code> y <code>pveam.log</code> antes de sincronizar — el comando <code>log2ram write</code> por sí solo copia tmpfs a disco pero NO reduce la tmpfs, así que este guardián evita que PVE caiga con <em>No space left on device</em> cuando los logs crecen sin control.",
"Instala un guardián de auto-sync en <code>/usr/local/bin/log2ram-check.sh</code>, conectado a <code>/etc/cron.d/log2ram-auto-sync</code> para ejecutarse cada 10 minutos. Cuando <code>/var/log</code> alcanza el 80% del tamaño de la ramdisk el guardián compacta journald; al 92% primero ejecuta <code>logrotate -f /etc/logrotate.d/proxmox-backup-api</code> si ese archivo existe (para forzar la rotación de los logs del API de PBS, que suelen ser los que más crecen en un host con PBS) y a continuación trunca <code>pveproxy access/error</code> y <code>pveam.log</code> antes de sincronizar. El comando <code>log2ram write</code> por sí solo copia tmpfs a disco pero NO reduce la tmpfs, así que este guardián evita que PVE caiga con <em>No space left on device</em> cuando los logs crecen sin control.",
"Detecta si <code>proxmox-backup-server</code> corre como servicio en el host. Cuando está presente, deposita <code>/etc/logrotate.d/proxmox-backup-api</code> (rotación de 20 MB × 3) y <code>/etc/cron.hourly/proxmox-backup-logrotate</code>, de forma que los logs del API de PBS — el origen habitual del crecimiento en un host con PBS — queden acotados incluso entre las sincronizaciones periódicas de Log2RAM. En hosts sin PBS este paso es un no-op.",
"Ajusta los límites de systemd-journald (<code>SystemMaxUse</code>, <code>RuntimeMaxUse</code>) para que quepan en la ramdisk y así una ráfaga puntual no la llene.",
"Se registra en <code>installed_tools.json</code> para poder revertirlo desde Uninstall Optimizations."
],

View File

@@ -18,30 +18,26 @@
"intro": "El <strong>Adaptive Replacement Cache (ARC)</strong> es la caché de lectura en memoria de ZFS. Sin tuning explícito, ZFS coge alegremente hasta la mitad de la RAM del host para sí mismo, lo que es excesivo en un host Proxmox que también necesita memoria para VMs y LXCs. Esta opción limita el ARC a una fracción sensata de la RAM total según el tamaño de la máquina.",
"sizingTitle": "Reglas de dimensionado",
"headerRam": "RAM del host",
"headerMin": "ARC mín",
"headerMax": "ARC máx",
"headerMax": "Cap ARC",
"rows": [
{
"ram": "≤ 16 GB",
"min": "512 MB",
"max": "512 MB"
"max": "512 MiB"
},
{
"ram": "17 32 GB",
"min": "1 GB",
"max": "1 GB"
"max": "1 GiB"
},
{
"ram": "> 32 GB",
"min": "RAM / 16",
"max": "RAM / 8"
"max": "RAM / 8 (mínimo 512 MiB)"
}
],
"after": "En un host de 64 GB, eso significa 4 GB mín / 8 GB máx para el ARC. La config se escribe en <code>/etc/modprobe.d/99-zfsarc.conf</code> y activa unos cuantos tunables ZFS extra (L2ARC prefetch activo, L2ARC write max en 500 MB, timeout TXG más largo).",
"after": "En un host de 64 GB, eso se traduce en un cap de 8 GB para el ARC. El archivo <code>/etc/modprobe.d/99-zfsarc.conf</code> contiene una única directiva — <code>options zfs zfs_arc_max=…</code>. El resto de parámetros del módulo (<code>zfs_arc_min</code>, prefetch/write throttle de L2ARC, timeout de TXG) se dejan en los valores por defecto de OpenZFS. Tras escribir el archivo, ProxMenux ejecuta <code>update-initramfs -u -k all</code> y, cuando corresponde, <code>proxmox-boot-tool refresh</code>, para que el cap llegue también al initramfs que usan las instalaciones con ZFS-on-root.",
"rebootTitle": "Requiere reinicio para surtir efecto",
"rebootBody": "Los ajustes del ARC se leen cuando se carga el módulo del kernel <code>zfs</code>. <strong>No</strong> se aplican en un sistema en vivo — necesitarás reiniciar el host para que el límite entre en juego. El script activa el flag de \"se requiere reinicio\" automáticamente.",
"rebootBody": "Los ajustes del ARC se leen cuando se carga el módulo del kernel <code>zfs</code>. Para que el cap se aplique en hosts ZFS-on-root, ProxMenux regenera el initramfs con <code>update-initramfs -u -k all</code> y, cuando corresponde, refresca el cargador de arranque con <code>proxmox-boot-tool refresh</code>. Un reinicio sigue siendo necesario para que el módulo relea el parámetro; el flag de \"se requiere reinicio\" se activa automáticamente.",
"safeTitle": "Seguro en hosts sin ZFS",
"safeBody": "La función comprueba el comando <code>zfs</code> antes de tocar nada. En hosts Proxmox solo ext4 / LVM, marcar esta opción es un no-op — no se escribe nada.",
"safeBody": "La función solo escribe la configuración cuando <code>zpool list</code> reporta al menos un pool ZFS importado. En hosts Proxmox solo ext4 / LVM, o en máquinas con las utilidades ZFS instaladas pero sin ningún pool importado, marcar esta opción es un no-op — no se escribe nada.",
"verifyTitle": "Verificación y rollback manual"
},
"autoSnap": {

View File

@@ -88,11 +88,11 @@
"items": [
{
"tool": "Network Optimizations",
"restores": "Elimina /etc/sysctl.d/99-network.conf y la unit proxmenux-fwbr-tune.service. Recarga sysctl y systemd."
"restores": "Elimina /etc/sysctl.d/99-network.conf junto con la unit proxmenux-fwbr-tune.service, el helper /usr/local/sbin/proxmenux-fwbr-tune y la regla /etc/udev/rules.d/99-proxmenux-fwbr-tune.rules. Recarga sysctl, systemd y el conjunto de reglas udev."
},
{
"tool": "Persistent Interface Names",
"restores": "Elimina cada archivo .link de /etc/systemd/network/. Los nombres de interfaz vuelven al comportamiento por defecto de systemd en el siguiente reinicio."
"restores": "Elimina solo los archivos 10-proxmenux-*.link que llevan la cabecera de ProxMenux en /etc/systemd/network/. Cualquier archivo .link provisto por otro paquete o escrito por el usuario se mantiene intacto. Los nombres de interfaz vuelven al comportamiento por defecto de systemd en el siguiente reinicio."
}
]
},
@@ -171,7 +171,7 @@
"packageTitle": "La reinstalación de paquetes toca paquetes vivos de Proxmox",
"packageBody": "Revertir <strong>Subscription Banner Removal</strong> reinstala <code>pve-manager</code>, <code>proxmox-widget-toolkit</code>, <code>libjs-extjs</code> y <code>libpve-http-server-perl</code> con <code>--force-confnew</code>. Es generalmente seguro pero sí toca la UI web en ejecución — refresca tu navegador después, y espera unos segundos de reconexión. No lo ejecutes a mitad de una migración o una operación de clonado.",
"rebootTitle": "Los nombres persistentes y VFIO necesitan reinicio",
"rebootBody": "Eliminar los archivos <code>.link</code> (<em>Persistent Interface Names</em>) y revertir <em>IOMMU/VFIO</em> no afectan al sistema en ejecución — solo importan tras un reinicio. ProxMenux activa el flag de reinicio automáticamente para estos.",
"rebootBody": "Eliminar los archivos <code>10-proxmenux-*.link</code> propios de ProxMenux (<em>Persistent Interface Names</em>) y revertir <em>IOMMU/VFIO</em> no afectan al sistema en ejecución — solo importan tras un reinicio. ProxMenux activa el flag de reinicio automáticamente para estos.",
"perItemTitle": "Puedes revertir una cosa y mantener el resto",
"perItemBody": "El uninstaller opera por item. Si solo quieres eliminar Log2RAM pero mantener el tuning de red y los cambios de bashrc, marca solo <em>Log2RAM</em>. Nada más se toca, y el registro se actualiza en consecuencia."
},

View File

@@ -53,7 +53,8 @@
"Tu configuración existente, login de ProxMenux Monitor (<code>auth.json</code>), canales de notificación, registro post-instalación, umbrales personalizados — nada de eso se toca. El cambio de canal solo intercambia el árbol de scripts y el AppImage binario.",
"Un Monitor que estaba activo antes del cambio sigue activo después; uno que estaba desactivado sigue desactivado.",
"El <code>auth.json</code>, los tokens de API y el secreto JWT de ProxMenux Monitor se preservan entre cambios de canal. Las sesiones no se cierran.",
"Puedes saltar de canal tantas veces como quieras — el diálogo lo aceptará cada vez y volverá a ejecutar el instalador. No hace falta reiniciar Proxmox."
"Puedes saltar de canal tantas veces como quieras — el diálogo lo aceptará cada vez y volverá a ejecutar el instalador. No hace falta reiniciar Proxmox.",
"El instalador de cambio de canal reemplaza el propio árbol de scripts de ProxMenux, así que no puede correr dentro del terminal del navegador del Monitor (esa PTY sería desmontada a mitad de la actualización y dejaría el diálogo colgado). Si lanzas la opción desde ahí, la confirmación se sustituye por un msgbox informativo con el instalador canónico de una línea para el canal de destino; ejecuta ese comando desde una sesión SSH o desde la consola del host Proxmox."
]
},
"feedback": {

View File

@@ -7,7 +7,7 @@
},
"header": {
"title": "Actualización del sistema Proxmox",
"description": "Wrapper que detecta la versión mayor de Proxmox en ejecución y delega en el worker correspondiente (PVE 8 o PVE 9). Los repos se limpian, se habilita la fuente sin suscripción, se actualizan todos los paquetes, se eliminan los paquetes conflictivos y el sistema se limpia después. El preguntar antes de reiniciar solo se dispara cuando el kernel realmente se ha actualizado.",
"description": "Wrapper que delega en un único worker seguro (<code>update-pve-safe.sh</code>) que detecta la versión mayor de Proxmox por sí mismo. Los repositorios se limpian cuando se solapan con las fuentes base de Proxmox / Debian, se actualizan todos los paquetes, se recompilan los drivers DKMS gestionados por ProxMenux si aterriza un kernel nuevo y el prompt de reinicio solo se dispara cuando el kernel realmente cambió. También lanzable desde el botón <em>Update Now</em> de la cabecera del dashboard de ProxMenux Monitor cuando se detectan actualizaciones pendientes.",
"section": "Utilidades"
},
"calloutWhat": {
@@ -22,15 +22,15 @@
},
"onTop": {
"heading": "Qué hace ProxMenux encima — verificado contra el script",
"intro": "Esta opción ejecuta <strong>exactamente</strong> el comando apt de arriba, envuelto con la higiene de repos y la limpieza post-upgrade que la guía oficial de upgrade también recomienda. La lista de abajo mapea 1:1 a <code>scripts/utilities/proxmox_update.sh</code> y a los scripts worker por versión — nada implícito, cada paso está en el código:",
"intro": "Esta opción ejecuta <strong>exactamente</strong> el comando apt de arriba, envuelto con la higiene de repos, la recompilación DKMS de los drivers gestionados por ProxMenux y la limpieza post-upgrade que la guía oficial de upgrade también recomienda. Todo lo de abajo mapea 1:1 a <code>scripts/utilities/proxmox_update.sh</code> y al único worker seguro <code>scripts/global/update-pve-safe.sh</code> — nada implícito, cada paso está en el código:",
"items": [
"<strong>Detecta la versión mayor de PVE</strong> (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>) y despacha a <code>update-pve8.sh</code> o <code>update-pve9_2.sh</code> para que se usen el codename y las URLs de repo correctas.",
"<strong>Limpia los repositorios</strong> antes de tocar apt: deshabilita la fuente enterprise (que devuelve 401 sin suscripción), elimina archivos de repo heredados y escribe una fuente sin suscripción limpia para el codename del host.",
"<strong>Ejecuta el upgrade no interactivamente</strong> con <code>DEBIAN_FRONTEND=noninteractive</code> y <code>--force-confdef --force-confold</code> — esto significa que si un archivo de configuración que ya modificaste también cambió upstream, tu versión se queda en su sitio. Sin sobrescrituras silenciosas de configuraciones propias.",
"<strong>Instala paquetes esenciales de Proxmox</strong> si falta alguno (<code>zfsutils-linux</code>, <code>proxmox-backup-restore-image</code>, <code>chrony</code>).",
"<strong>Detecta la versión mayor de PVE</strong> desde dentro del worker (<code>pveversion | grep -oP ''pve-manager/\\K[0-9]+''</code>) y adapta las URLs base de repo Proxmox / Debian (bookworm en PVE 8, trixie en PVE 9). No hay reparto a scripts worker por versión — un único worker seguro maneja ambas.",
"<strong>Limpia los repositorios de forma conservadora.</strong> <code>ensure_repositories</code> se ejecuta primero pero solo cuando faltan las fuentes base de Proxmox / Debian — un host bare las recibe escritas, un host configurado es un no-op. <code>cleanup_duplicate_repos</code> elimina después duplicados exactos por URL + Suite + Component solo contra <code>proxmox.sources</code> / <code>debian.sources</code>; los archivos propios del usuario (enterprise, Ceph, mirrors NTP alternativos, entradas custom de <code>download.proxmox.com/*</code> o <code>pve-*.list</code> escritos a mano) no se tocan, y cada archivo se respalda antes de editarse.",
"<strong>Ejecuta el upgrade no interactivamente</strong> con <code>DEBIAN_FRONTEND=noninteractive</code> y <code>--force-confdef --force-confold</code> — si un archivo de configuración que ya modificaste también cambió upstream, tu versión se queda en su sitio. Sin sobrescrituras silenciosas de configuraciones propias.",
"<strong>No fuerza utilidades opcionales.</strong> El worker seguro no empuja <code>zfsutils-linux</code>, <code>chrony</code>, <code>ifupdown2</code> ni paquetes similares al host — una instalación de Proxmox que optó por no tener alguno de ellos conserva su elección. La ausencia de paquetes la surface los flujos de instalación de alto nivel, no la ruta de actualización.",
"<strong>Comprobación de sanity de metadatos LVM</strong> contra cabeceras PV sueltas de discos en passthrough (solo aviso, sin arreglo automático).",
"<strong>Limpia después:</strong> <code>apt-get autoremove -y</code> + <code>apt-get autoclean -y</code>.",
"<strong>Preguntar antes de reiniciar</strong> solo si el kernel realmente cambió (presencia de <code>/var/run/reboot-required</code> o <code>linux-image</code> en el log del upgrade)."
"<strong>Recompilación DKMS antes del prompt de reinicio.</strong> Cuando el upgrade dejó staged un kernel nuevo, el wrapper llama a <code>pmx_rebuild_dkms_after_kernel</code> para recompilar cada driver que ProxMenux instaló vía DKMS contra la versión del kernel entrante — así los módulos están listos antes de que la caja vuelva a arrancar. La detección de reinicio usa <code>/var/run/reboot-required</code> cuando <code>needrestart</code> está presente, y como fallback una comparación por <code>dpkg-query</code> entre el kernel en ejecución y el paquete <code>proxmox-kernel-*-pve-signed</code> / <code>pve-kernel-*-pve</code> más nuevo instalado cuando no lo está — señal que sobrevive a los muchos hosts Proxmox que se entregan sin <code>needrestart</code>."
]
},
"calloutOneSentence": {
@@ -50,8 +50,8 @@
"detail": "pveversion |\ngrep -oP ''pve-manager/\\K[0-9]+''"
},
"bridge": {
"label": "Selección del worker",
"detail": "PVE 8 → update-pve8.sh\nPVE 9 → update-pve9_2.sh"
"label": "Único worker seguro",
"detail": "update-pve-safe.sh\n(detecta PVE 8 / 9\ninternamente)"
},
"target": {
"label": "Post-actualización",
@@ -61,13 +61,18 @@
},
"worker": {
"heading": "Qué hace el worker",
"intro": "Ambos workers (<code>scripts/global/update-pve8.sh</code> para PVE 8 y <code>scripts/global/update-pve9_2.sh</code> para PVE 9) siguen el mismo esquema, con URLs de repo y nombres de paquete propios de cada versión:",
"intro": "Un único worker (<code>scripts/global/update-pve-safe.sh</code>) maneja tanto PVE 8 como PVE 9. Detecta la versión mayor internamente y usa el codename propio de cada versión (<code>bookworm</code> o <code>trixie</code>) para sus fuentes base. Las etapas son:",
"items": [
"<strong>Higiene de repos.</strong> Elimina entradas duplicadas de <code>/etc/apt/sources.list</code> y <code>/etc/apt/sources.list.d/</code>. Comenta el repo enterprise si el host no tiene suscripción y escribe / habilita la fuente sin suscripción.",
"<strong>Apt update + full-upgrade.</strong> Trae las últimas listas de paquetes y aplica todas las actualizaciones disponibles para la versión mayor actual, ejecutándose con <code>DEBIAN_FRONTEND=noninteractive</code> y <code>--force-confdef --force-confold</code> para que cualquier archivo de configuración que personalizaste mantenga su contenido actual cuando upstream también lo cambió.",
"<strong>Comprobación de paquetes esenciales.</strong> Instala <code>zfsutils-linux</code>, <code>chrony</code>, <code>ifupdown2</code> y unos pocos más si el host no los tiene.",
"<strong>Comprobación de sanity de LVM / almacenamiento.</strong> Repara cabeceras PV faltantes si se detectan.",
"<strong>Eliminación de paquetes conflictivos.</strong> Quita paquetes conocidos por chocar en Proxmox (p. ej. algunos demonios de sincronización horaria que pelean con chrony)."
"<strong>Comprobaciones previas.</strong> Verifica al menos ~1 GB libres en <code>/var/cache/apt/archives</code> y hace ping a <code>download.proxmox.com</code>. Aborta pronto con un mensaje claro cuando falla cualquiera de las dos, para que la ejecución no muera a mitad de una transacción apt.",
"<strong>Bootstrap de repos.</strong> <code>ensure_repositories</code> escribe las fuentes base Proxmox / Debian solo cuando faltan (un host fresco o limpiado a mano); en un host configurado no hace nada.",
"<strong>Apt update con auto-recuperación de GPG.</strong> Ante un <code>NO_PUBKEY</code> de cualquier repo (los propios o uno de terceros), el worker importa la clave que falta y vuelve a intentar automáticamente antes de fallar.",
"<strong>Limpieza conservadora de duplicados.</strong> <code>cleanup_duplicate_repos</code> elimina solo coincidencias exactas por URL + Suite + Component contra <code>proxmox.sources</code> / <code>debian.sources</code>. Los archivos propios del usuario — enterprise, Ceph, mirrors NTP alternativos, entradas custom de <code>download.proxmox.com/*</code>, <code>pve-*.list</code> escritos a mano — se dejan intactos. Cada archivo se respalda antes de modificarse.",
"<strong>Actualizaciones pendientes + conteo de seguridad.</strong> Reporta cuántos paquetes van a cambiar y cuántos de esos vienen de la suite de seguridad, para que el diálogo de confirmación tenga números reales que mostrar.",
"<strong>Diálogo de confirmación.</strong> El wrapper pide un sí explícito antes de tocar apt.",
"<strong>apt full-upgrade.</strong> Se ejecuta con <code>DEBIAN_FRONTEND=noninteractive</code> y <code>--force-confdef --force-confold</code> para que cualquier archivo de configuración que personalizaste mantenga su contenido actual cuando upstream también lo cambió. Nunca sobrescribe silenciosamente configs editados por el usuario.",
"<strong>Comprobación de sanity LVM.</strong> <code>lvm_repair_check</code> refresca los metadatos de VG cuando discos en passthrough a VMs guest (DSM, TrueNAS, appliances de almacenamiento) vuelven con cabeceras PV antiguas.",
"<strong>Recompilación DKMS de los drivers gestionados por ProxMenux.</strong> Cuando el upgrade dejó staged un kernel nuevo, <code>pmx_rebuild_dkms_after_kernel</code> lee <code>components_status.json</code> para los drivers que ProxMenux instaló (actualmente <code>nvidia_driver</code> → módulo <code>nvidia</code>, <code>coral_driver</code> → módulo <code>gasket</code>), instala los headers de kernel correspondientes (<code>proxmox-headers-&lt;newkver&gt;</code> cuando está disponible, si no <code>pve-headers-&lt;newkver&gt;</code>) y ejecuta <code>dkms autoinstall -k &lt;newkver&gt;</code>. Si <code>dkms status</code> no muestra los módulos construidos contra el kernel nuevo, el worker cae a reejecutar cada instalador con <code>--auto-reinstall</code>. Cualquier fallo se registra pero no aborta la actualización — llegas al prompt de reinicio en todos los casos.",
"<strong>Post-limpieza.</strong> <code>apt-get autoremove</code> + <code>apt-get autoclean</code> antes de devolver el control al wrapper."
]
},
"post": {
@@ -91,14 +96,14 @@
"body": "Correr en un kernel antiguo tras actualizar <code>linux-image-*</code> significa que estás en un sistema medio actualizado: userspace nuevo, kernel viejo. La mayoría del tiempo las cosas funcionan, pero los módulos ZFS, grupos IOMMU, KSMBD y cualquier driver fuera del árbol solo cuadran con el kernel para el que fueron construidos — un desajuste produce fallos oscuros. Reinicia en el primer momento razonable."
},
"noSub": {
"heading": "Cuándo ocurre el cambio a sin suscripción",
"intro": "Proxmox entrega los hosts con el repo enterprise habilitado por defecto. Sin una suscripción de pago, ese repo devuelve 401 en <code>apt-get update</code>. El worker detecta esto y:",
"heading": "Cómo trata el worker seguro al repo enterprise",
"intro": "Proxmox entrega los hosts con el repo enterprise habilitado por defecto. Sin una suscripción de pago, ese repo devuelve 401 en <code>apt-get update</code>. El worker seguro deliberadamente <strong>no</strong> toca los repositorios enterprise ni Ceph — un host corriendo con una suscripción real no debe verse la configuración reescrita en silencio. Lo que ocurre en su lugar:",
"items": [
"Comenta (o deshabilita) <code>/etc/apt/sources.list.d/pve-enterprise.list</code> (o el equivalente deb822)",
"Escribe <code>/etc/apt/sources.list.d/pve-no-subscription.list</code> (o el deb822 <code>proxmox.sources</code> para PVE 9) con el codename correspondiente (<code>bookworm</code> para PVE 8, <code>trixie</code> para PVE 9)",
"Vuelve a ejecutar <code>apt-get update</code>"
"En un <strong>host bare</strong> sin fuentes base de Proxmox / Debian, <code>ensure_repositories</code> escribe la fuente sin suscripción en formato deb822 (<code>proxmox.sources</code>) con el codename correspondiente a la versión mayor detectada (<code>bookworm</code> para PVE 8, <code>trixie</code> para PVE 9) y las fuentes Debian correspondientes.",
"En un <strong>host configurado</strong>, <code>ensure_repositories</code> es un no-op — lo que el usuario haya elegido (sin suscripción, enterprise o una mezcla) se preserva.",
"Los archivos enterprise <code>pve-enterprise.sources</code> / <code>ceph.sources</code> nunca son modificados por la ruta de actualización. La eliminación del repo enterprise cuando no se quiere se gestiona desde otra parte de ProxMenux (el script post-instalación automatizado), no desde aquí."
],
"outro": "Si tienes una suscripción de pago, comenta la fuente sin suscripción y descomenta la enterprise antes de ejecutar esta opción."
"outro": "Si tienes una suscripción de pago, mantén <code>pve-enterprise.sources</code> habilitado y el worker seguro lo dejará dirigir el upgrade sin cambios. Si no la tienes, o bien ejecuta primero el post-instalación automatizado (que hace el cambio y lo registra) o comenta la fuente enterprise a mano — la ruta de actualización no lo hará por ti."
},
"cluster": {
"heading": "Consideraciones de clúster",
@@ -127,7 +132,7 @@
},
{
"title": "El kernel se actualizó pero los nuevos módulos faltan para un driver fuera del árbol",
"body": "Los módulos fuera del árbol (NVIDIA, ZFS vía DKMS, drivers de NIC propios) necesitan reconstruirse contra el nuevo kernel. La mayoría los gestiona automáticamente DKMS durante el upgrade — confirma con <code>dkms status</code>. Si falta algo: <code>dkms autoinstall</code>."
"body": "Los drivers que ProxMenux instaló vía DKMS (actualmente <code>nvidia_driver</code> y <code>coral_driver</code>) se recompilan automáticamente al final del upgrade contra la versión del kernel entrante, usando <code>dkms autoinstall -k &lt;newkver&gt;</code> y, si hace falta, un fallback a cada instalador con <code>--auto-reinstall</code>. Confirma con <code>dkms status</code>. Los módulos fuera del árbol de terceros que no están en el registro <code>components_status.json</code> de ProxMenux (drivers de NIC propios, paquetes DKMS instalados a mano, …) siguen necesitando un <code>dkms autoinstall</code> manual — el worker seguro solo toca lo que instaló originalmente."
},
{
"title": "El preguntar antes de reiniciar no apareció pero estoy seguro de que el kernel cambió",
@@ -137,7 +142,7 @@
},
"files": {
"heading": "Archivos implicados",
"code": "scripts/utilities/proxmox_update.sh # this script (wrapper)\nscripts/global/update-pve8.sh # worker for PVE 8 hosts\nscripts/global/update-pve9_2.sh # worker for PVE 9 hosts\nscripts/global/common-functions.sh # cleanup_duplicate_repos used by workers\n/etc/apt/sources.list # may be edited\n/etc/apt/sources.list.d/* # may be edited / created\n/var/run/reboot-required # read to decide on reboot prompt\n/var/log/apt/history.log # read to detect kernel changes"
"code": "scripts/utilities/proxmox_update.sh # este script (wrapper)\nscripts/global/update-pve-safe.sh # único worker seguro (PVE 8 + PVE 9)\nscripts/global/common-functions.sh # cleanup_duplicate_repos usado por el worker\nscripts/global/utils-install-functions.sh # ensure_repositories + pmx_rebuild_dkms_after_kernel\n/usr/local/share/proxmenux/components_status.json # registro de drivers DKMS gestionados por ProxMenux\n/etc/apt/sources.list.d/proxmox.sources # fuente deb822 sin suscripción (bootstrap host bare)\n/etc/apt/sources.list.d/debian.sources # fuentes deb822 de Debian (bootstrap host bare)\n/var/run/reboot-required # se lee para decidir el prompt de reinicio\n# Fallback de reinicio cuando needrestart no está instalado:\n# dpkg-query -W 'proxmox-kernel-*-pve-signed' 'pve-kernel-*-pve' vs. uname -r"
},
"related": {
"heading": "Relacionado",