Keep guest services off PBS hosts, refuse only known PBS in PVE scripts and follow the menu conventions

- On a PBS host the Monitor no longer starts the node metrics and VM prewarmers, the LXC update scheduler, the managed installs detector or the app update emitter, which read guests and PVE metrics that do not exist there
- pmx_require_pve refuses only a host known to be PBS, so an unreadable package list leaves the PVE scripts working as before
- The PBS menu numbers its options, shows the tables proxmox-backup-manager prints instead of raw JSON, and says Goodbye on exit
- The PBS update asks to press Enter before returning
- Spanish: Datastores de PBS
This commit is contained in:
MacRimi
2026-10-17 10:01:37 +02:00
parent 69b2dc31d0
commit 08ae134860
6 changed files with 70 additions and 42 deletions
+22 -13
View File
@@ -23193,9 +23193,11 @@ if __name__ == '__main__':
except Exception as e: except Exception as e:
print(f"[ProxMenux] Disk temperature history init failed: {e}") print(f"[ProxMenux] Disk temperature history init failed: {e}")
try: try:
import managed_installs # A PBS host has no guests whose applications could be tracked.
managed_installs.detect_and_register() if not is_pbs_host():
print("[ProxMenux] Managed-installs registry initialised") import managed_installs
managed_installs.detect_and_register()
print("[ProxMenux] Managed-installs registry initialised")
except Exception as e: except Exception as e:
print(f"[ProxMenux] managed_installs init failed: {e}") print(f"[ProxMenux] managed_installs init failed: {e}")
# Docker inventories are derived runtime data and intentionally # Docker inventories are derived runtime data and intentionally
@@ -23337,6 +23339,9 @@ if __name__ == '__main__':
# the 24 h PollingCollector cycle. Runs in a daemon thread with # the 24 h PollingCollector cycle. Runs in a daemon thread with
# a delay so it doesn't block startup — notification_manager needs # a delay so it doesn't block startup — notification_manager needs
# a moment to bind channels before we emit. # a moment to bind channels before we emit.
# The guest services below read VMs, LXCs and the PVE node metrics,
# none of which exist on a Proxmox Backup Server.
pve_host = not is_pbs_host()
try: try:
def _startup_emit_pending_app_updates(): def _startup_emit_pending_app_updates():
time.sleep(15) # let channels bind + first metrics collect time.sleep(15) # let channels bind + first metrics collect
@@ -23346,16 +23351,18 @@ if __name__ == '__main__':
except Exception as e: except Exception as e:
print(f"[ProxMenux] startup emit_all_pending_updates failed: {e}", print(f"[ProxMenux] startup emit_all_pending_updates failed: {e}",
file=sys.stderr, flush=True) file=sys.stderr, flush=True)
threading.Thread(target=_startup_emit_pending_app_updates, daemon=True, if pve_host:
name='app-updates-startup-emit').start() threading.Thread(target=_startup_emit_pending_app_updates, daemon=True,
name='app-updates-startup-emit').start()
except Exception as e: except Exception as e:
print(f"[ProxMenux] app-updates startup emitter failed to arm: {e}") print(f"[ProxMenux] app-updates startup emitter failed to arm: {e}")
# Prewarm only the Overview's default day range; other ranges are lazy. # Prewarm only the Overview's default day range; other ranges are lazy.
try: try:
metrics_thread = threading.Thread(target=_node_metrics_prewarmer_loop, daemon=True, name='node-metrics-prewarmer') if pve_host:
metrics_thread.start() metrics_thread = threading.Thread(target=_node_metrics_prewarmer_loop, daemon=True, name='node-metrics-prewarmer')
print("[ProxMenux] Node-metrics prewarmer started (day range, 90s interval)") metrics_thread.start()
print("[ProxMenux] Node-metrics prewarmer started (day range, 90s interval)")
except Exception as e: except Exception as e:
print(f"[ProxMenux] Node-metrics prewarmer failed to start: {e}") print(f"[ProxMenux] Node-metrics prewarmer failed to start: {e}")
@@ -23366,9 +23373,10 @@ if __name__ == '__main__':
# after the tab has been closed for minutes. The React-side # after the tab has been closed for minutes. The React-side
# prefetcher only ran while the page was open. # prefetcher only ran while the page was open.
try: try:
vm_modal_thread = threading.Thread(target=_vm_modal_prewarmer_loop, daemon=True, name='vm-modal-prewarmer') if pve_host:
vm_modal_thread.start() vm_modal_thread = threading.Thread(target=_vm_modal_prewarmer_loop, daemon=True, name='vm-modal-prewarmer')
print("[ProxMenux] VM-modal prewarmer started (one-shot warm-up; caches refreshed by event invalidation only)") vm_modal_thread.start()
print("[ProxMenux] VM-modal prewarmer started (one-shot warm-up; caches refreshed by event invalidation only)")
except Exception as e: except Exception as e:
print(f"[ProxMenux] VM-modal prewarmer failed to start: {e}") print(f"[ProxMenux] VM-modal prewarmer failed to start: {e}")
@@ -23392,8 +23400,9 @@ if __name__ == '__main__':
# identical (backup, restart, /usr/bin/update + custom command # identical (backup, restart, /usr/bin/update + custom command
# chain) between manual and scheduled invocations. # chain) between manual and scheduled invocations.
try: try:
scheduler_thread = threading.Thread(target=_scheduler_loop, daemon=True) if pve_host:
scheduler_thread.start() scheduler_thread = threading.Thread(target=_scheduler_loop, daemon=True)
scheduler_thread.start()
except Exception as e: except Exception as e:
print(f"[ProxMenux] LXC update scheduler failed to start: {e}") print(f"[ProxMenux] LXC update scheduler failed to start: {e}")
+7
View File
@@ -3850,6 +3850,13 @@ class PollingCollector:
return return
self._last_managed_check = now self._last_managed_check = now
try:
from pbs_manager import is_pbs_host
if is_pbs_host():
return # a Proxmox Backup Server has no guests or integrations to track
except Exception:
pass
try: try:
import managed_installs import managed_installs
except Exception: except Exception:
+1 -1
View File
@@ -8132,7 +8132,7 @@
"Apply PBS package upgrade": "Aplicar la actualización de paquetes de PBS", "Apply PBS package upgrade": "Aplicar la actualización de paquetes de PBS",
"Apply the reviewed package upgrade now? Services may restart and packages listed for removal will be removed.": "¿Aplicar ahora la actualización de paquetes revisada? Los servicios podrían reiniciarse y se eliminarán los paquetes indicados para su eliminación.", "Apply the reviewed package upgrade now? Services may restart and packages listed for removal will be removed.": "¿Aplicar ahora la actualización de paquetes revisada? Los servicios podrían reiniciarse y se eliminarán los paquetes indicados para su eliminación.",
"Command failed": "El comando ha fallado", "Command failed": "El comando ha fallado",
"PBS datastores": "Almacenes de datos de PBS", "PBS datastores": "Datastores de PBS",
"PBS package update": "Actualización de paquetes de PBS", "PBS package update": "Actualización de paquetes de PBS",
"PBS package upgrade completed. Check whether a reboot is required before your next backup window.": "Actualización de paquetes de PBS completada. Comprueba si es necesario reiniciar antes del próximo período de copias de seguridad.", "PBS package upgrade completed. Check whether a reboot is required before your next backup window.": "Actualización de paquetes de PBS completada. Comprueba si es necesario reiniciar antes del próximo período de copias de seguridad.",
"PBS package upgrade failed. Review the APT output before retrying.": "La actualización de paquetes de PBS ha fallado. Revisa la salida de APT antes de volver a intentarlo.", "PBS package upgrade failed. Review the APT output before retrying.": "La actualización de paquetes de PBS ha fallado. Revisa la salida de APT antes de volver a intentarlo.",
+3 -1
View File
@@ -8,8 +8,10 @@ pmx_is_pbs() {
[[ "$(pmx_platform_field product)" == pbs ]] [[ "$(pmx_platform_field product)" == pbs ]]
} }
# Only a host known to be PBS is refused: if the package list cannot be read,
# the PVE scripts keep working as they did before PBS support.
pmx_require_pve() { pmx_require_pve() {
if [[ "$(pmx_platform_field product)" != pve ]]; then if pmx_is_pbs; then
msg_error "$(translate 'This operation requires a Proxmox VE host. Use the PBS menu on Proxmox Backup Server.')" msg_error "$(translate 'This operation requires a Proxmox VE host. Use the PBS menu on Proxmox Backup Server.')"
return 1 return 1
fi fi
+27 -20
View File
@@ -1,5 +1,10 @@
#!/bin/bash #!/bin/bash
# PBS exposes compatible host tools; PVE guest/repository optimizations stay in the PVE menu. # ==========================================================
# ProxMenux - Proxmox Backup Server menu
# ==========================================================
# PBS exposes compatible host tools; PVE guest/repository optimizations
# stay in the PVE menu.
# ==========================================================
BASE_DIR="/usr/local/share/proxmenux" BASE_DIR="/usr/local/share/proxmenux"
LOCAL_SCRIPTS="$BASE_DIR/scripts" LOCAL_SCRIPTS="$BASE_DIR/scripts"
source "$BASE_DIR/utils.sh" source "$BASE_DIR/utils.sh"
@@ -13,34 +18,36 @@ if ! pmx_is_pbs; then
fi fi
pbs_show() { pbs_show() {
local output local title="$1" output
shift
output=$(mktemp) output=$(mktemp)
if "$@" > "$output" 2>&1; then if "$@" > "$output" 2>&1; then
dialog --backtitle "ProxMenux · PBS" --title "Proxmox Backup Server" --textbox "$output" 24 100 dialog --backtitle "ProxMenux" --title "$title" --textbox "$output" 24 110
else else
dialog --backtitle "ProxMenux · PBS" --title "$(translate 'Command failed')" --textbox "$output" 24 100 dialog --backtitle "ProxMenux" --title "$(translate 'Command failed')" --textbox "$output" 24 110
fi fi
rm -f "$output" rm -f "$output"
} }
while true; do while true; do
choice=$(dialog --clear --backtitle "ProxMenux · PBS" --title "Proxmox Backup Server" \ choice=$(dialog --clear --backtitle "ProxMenux" --title "Proxmox Backup Server" \
--menu "$(translate 'Select an option:')" 20 80 10 \ --menu "$(translate 'Select an option:')" 18 75 8 \
status "$(translate 'PBS version and packages')" \ 1 "$(translate 'PBS version and packages')" \
stores "$(translate 'PBS datastores')" \ 2 "$(translate 'PBS datastores')" \
tasks "$(translate 'Recent PBS tasks')" \ 3 "$(translate 'Recent PBS tasks')" \
utilities "$(translate 'System Utilities Installer')" \ 4 "$(translate 'System Utilities Installer')" \
update "$(translate 'Update PBS using configured repositories')" \ 5 "$(translate 'Update PBS using configured repositories')" \
settings "$(translate 'Settings')" \ s "$(translate 'Settings')" \
exit "$(translate 'Exit')" 2>&1 >/dev/tty) || break 0 "$(translate 'Exit')" 2>&1 >/dev/tty) || break
case "$choice" in case "$choice" in
status) pbs_show proxmox-backup-manager versions --verbose --output-format json-pretty ;; 1) pbs_show "$(translate 'PBS version and packages')" proxmox-backup-manager versions --verbose ;;
stores) pbs_show proxmox-backup-manager datastore list --output-format json-pretty ;; 2) pbs_show "$(translate 'PBS datastores')" proxmox-backup-manager datastore list ;;
tasks) pbs_show proxmox-backup-manager task list --all true --limit 20 --output-format json-pretty ;; 3) pbs_show "$(translate 'Recent PBS tasks')" proxmox-backup-manager task list --all true --limit 20 ;;
utilities) bash "$LOCAL_SCRIPTS/utilities/system_utils.sh" ;; 4) bash "$LOCAL_SCRIPTS/utilities/system_utils.sh" ;;
update) bash "$LOCAL_SCRIPTS/utilities/pbs_update.sh" ;; 5) bash "$LOCAL_SCRIPTS/utilities/pbs_update.sh" ;;
settings) bash "$LOCAL_SCRIPTS/menus/config_menu.sh" ;; s) exec bash "$LOCAL_SCRIPTS/menus/config_menu.sh" ;;
exit) break ;; 0) break ;;
esac esac
done done
clear clear
msg_ok "$(translate "Thank you for using ProxMenux. Goodbye!")"
+10 -7
View File
@@ -12,27 +12,30 @@ if ! pmx_is_pbs || [[ "$(pmx_platform_field supported)" != true ]]; then
exit 1 exit 1
fi fi
[[ $EUID -eq 0 ]] || { msg_error "$(translate 'Run this operation as root.')"; exit 1; } [[ $EUID -eq 0 ]] || { msg_error "$(translate 'Run this operation as root.')"; exit 1; }
dialog --backtitle "ProxMenux · PBS" --title "$(translate 'PBS package update')" \ dialog --backtitle "ProxMenux" --title "$(translate 'PBS package update')" \
--yesno "$(translate 'Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.')" 10 80 || exit 0 --yesno "$(translate 'Refresh the configured APT repositories and review the PBS package upgrade? Repository files will be preserved.')" 10 80 || exit 0
if ! apt-get -o APT::Update::Error-Mode=any update; then if ! apt-get -o APT::Update::Error-Mode=any update; then
msg_error "$(translate 'APT refresh failed. Check the PBS subscription and repositories in the native PBS interface; no source was changed.')" msg_error "$(translate 'APT refresh failed. Check the PBS subscription and repositories in the native PBS interface; no source was changed.')"
read -r _ msg_success "$(translate "Press Enter to continue...")"
read -r
exit 1 exit 1
fi fi
plan=$(mktemp) plan=$(mktemp)
trap 'rm -f "$plan"' EXIT trap 'rm -f "$plan"' EXIT
if ! apt-get -s full-upgrade > "$plan" 2>&1; then if ! apt-get -s full-upgrade > "$plan" 2>&1; then
dialog --textbox "$plan" 24 100 dialog --backtitle "ProxMenux" --title "$(translate 'Review package upgrade')" --textbox "$plan" 24 100
exit 1 exit 1
fi fi
dialog --backtitle "ProxMenux · PBS" --title "$(translate 'Review package upgrade')" --textbox "$plan" 24 100 dialog --backtitle "ProxMenux" --title "$(translate 'Review package upgrade')" --textbox "$plan" 24 100
dialog --defaultno --title "$(translate 'Apply PBS package upgrade')" \ dialog --backtitle "ProxMenux" --defaultno --title "$(translate 'Apply PBS package upgrade')" \
--yesno "$(translate 'Apply the reviewed package upgrade now? Services may restart and packages listed for removal will be removed.')" 11 80 || exit 0 --yesno "$(translate 'Apply the reviewed package upgrade now? Services may restart and packages listed for removal will be removed.')" 11 80 || exit 0
if apt-get -y full-upgrade; then if apt-get -y full-upgrade; then
msg_ok "$(translate 'PBS package upgrade completed. Check whether a reboot is required before your next backup window.')" msg_ok "$(translate 'PBS package upgrade completed. Check whether a reboot is required before your next backup window.')"
else else
msg_error "$(translate 'PBS package upgrade failed. Review the APT output before retrying.')" msg_error "$(translate 'PBS package upgrade failed. Review the APT output before retrying.')"
read -r _ msg_success "$(translate "Press Enter to continue...")"
read -r
exit 1 exit 1
fi fi
read -r _ msg_success "$(translate "Press Enter to continue...")"
read -r