diff --git a/AppImage/scripts/flask_server.py b/AppImage/scripts/flask_server.py index d49452fc..3ffa0c4c 100644 --- a/AppImage/scripts/flask_server.py +++ b/AppImage/scripts/flask_server.py @@ -23193,9 +23193,11 @@ if __name__ == '__main__': except Exception as e: print(f"[ProxMenux] Disk temperature history init failed: {e}") try: - import managed_installs - managed_installs.detect_and_register() - print("[ProxMenux] Managed-installs registry initialised") + # A PBS host has no guests whose applications could be tracked. + if not is_pbs_host(): + import managed_installs + managed_installs.detect_and_register() + print("[ProxMenux] Managed-installs registry initialised") except Exception as e: print(f"[ProxMenux] managed_installs init failed: {e}") # 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 # a delay so it doesn't block startup — notification_manager needs # 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: def _startup_emit_pending_app_updates(): time.sleep(15) # let channels bind + first metrics collect @@ -23346,16 +23351,18 @@ if __name__ == '__main__': except Exception as e: print(f"[ProxMenux] startup emit_all_pending_updates failed: {e}", file=sys.stderr, flush=True) - threading.Thread(target=_startup_emit_pending_app_updates, daemon=True, - name='app-updates-startup-emit').start() + if pve_host: + threading.Thread(target=_startup_emit_pending_app_updates, daemon=True, + name='app-updates-startup-emit').start() except Exception as e: print(f"[ProxMenux] app-updates startup emitter failed to arm: {e}") # Prewarm only the Overview's default day range; other ranges are lazy. try: - metrics_thread = threading.Thread(target=_node_metrics_prewarmer_loop, daemon=True, name='node-metrics-prewarmer') - metrics_thread.start() - print("[ProxMenux] Node-metrics prewarmer started (day range, 90s interval)") + if pve_host: + metrics_thread = threading.Thread(target=_node_metrics_prewarmer_loop, daemon=True, name='node-metrics-prewarmer') + metrics_thread.start() + print("[ProxMenux] Node-metrics prewarmer started (day range, 90s interval)") except Exception as 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 # prefetcher only ran while the page was open. try: - vm_modal_thread = threading.Thread(target=_vm_modal_prewarmer_loop, daemon=True, name='vm-modal-prewarmer') - vm_modal_thread.start() - print("[ProxMenux] VM-modal prewarmer started (one-shot warm-up; caches refreshed by event invalidation only)") + if pve_host: + vm_modal_thread = threading.Thread(target=_vm_modal_prewarmer_loop, daemon=True, name='vm-modal-prewarmer') + vm_modal_thread.start() + print("[ProxMenux] VM-modal prewarmer started (one-shot warm-up; caches refreshed by event invalidation only)") except Exception as 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 # chain) between manual and scheduled invocations. try: - scheduler_thread = threading.Thread(target=_scheduler_loop, daemon=True) - scheduler_thread.start() + if pve_host: + scheduler_thread = threading.Thread(target=_scheduler_loop, daemon=True) + scheduler_thread.start() except Exception as e: print(f"[ProxMenux] LXC update scheduler failed to start: {e}") diff --git a/AppImage/scripts/notification_events.py b/AppImage/scripts/notification_events.py index cadfc136..2f71a2d4 100644 --- a/AppImage/scripts/notification_events.py +++ b/AppImage/scripts/notification_events.py @@ -3850,6 +3850,13 @@ class PollingCollector: return 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: import managed_installs except Exception: diff --git a/lang/es.json b/lang/es.json index 4de8be5d..58020c86 100644 --- a/lang/es.json +++ b/lang/es.json @@ -8132,7 +8132,7 @@ "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.", "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 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.", diff --git a/scripts/global/platform-functions.sh b/scripts/global/platform-functions.sh index 1bfb3e49..7ca2b240 100644 --- a/scripts/global/platform-functions.sh +++ b/scripts/global/platform-functions.sh @@ -8,8 +8,10 @@ pmx_is_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() { - 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.')" return 1 fi diff --git a/scripts/menus/pbs_menu.sh b/scripts/menus/pbs_menu.sh index 4a04c2a4..86f30ca2 100644 --- a/scripts/menus/pbs_menu.sh +++ b/scripts/menus/pbs_menu.sh @@ -1,5 +1,10 @@ #!/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" LOCAL_SCRIPTS="$BASE_DIR/scripts" source "$BASE_DIR/utils.sh" @@ -13,34 +18,36 @@ if ! pmx_is_pbs; then fi pbs_show() { - local output + local title="$1" output + shift output=$(mktemp) 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 - dialog --backtitle "ProxMenux · PBS" --title "$(translate 'Command failed')" --textbox "$output" 24 100 + dialog --backtitle "ProxMenux" --title "$(translate 'Command failed')" --textbox "$output" 24 110 fi rm -f "$output" } while true; do - choice=$(dialog --clear --backtitle "ProxMenux · PBS" --title "Proxmox Backup Server" \ - --menu "$(translate 'Select an option:')" 20 80 10 \ - status "$(translate 'PBS version and packages')" \ - stores "$(translate 'PBS datastores')" \ - tasks "$(translate 'Recent PBS tasks')" \ - utilities "$(translate 'System Utilities Installer')" \ - update "$(translate 'Update PBS using configured repositories')" \ - settings "$(translate 'Settings')" \ - exit "$(translate 'Exit')" 2>&1 >/dev/tty) || break + choice=$(dialog --clear --backtitle "ProxMenux" --title "Proxmox Backup Server" \ + --menu "$(translate 'Select an option:')" 18 75 8 \ + 1 "$(translate 'PBS version and packages')" \ + 2 "$(translate 'PBS datastores')" \ + 3 "$(translate 'Recent PBS tasks')" \ + 4 "$(translate 'System Utilities Installer')" \ + 5 "$(translate 'Update PBS using configured repositories')" \ + s "$(translate 'Settings')" \ + 0 "$(translate 'Exit')" 2>&1 >/dev/tty) || break case "$choice" in - status) pbs_show proxmox-backup-manager versions --verbose --output-format json-pretty ;; - stores) pbs_show proxmox-backup-manager datastore list --output-format json-pretty ;; - tasks) pbs_show proxmox-backup-manager task list --all true --limit 20 --output-format json-pretty ;; - utilities) bash "$LOCAL_SCRIPTS/utilities/system_utils.sh" ;; - update) bash "$LOCAL_SCRIPTS/utilities/pbs_update.sh" ;; - settings) bash "$LOCAL_SCRIPTS/menus/config_menu.sh" ;; - exit) break ;; + 1) pbs_show "$(translate 'PBS version and packages')" proxmox-backup-manager versions --verbose ;; + 2) pbs_show "$(translate 'PBS datastores')" proxmox-backup-manager datastore list ;; + 3) pbs_show "$(translate 'Recent PBS tasks')" proxmox-backup-manager task list --all true --limit 20 ;; + 4) bash "$LOCAL_SCRIPTS/utilities/system_utils.sh" ;; + 5) bash "$LOCAL_SCRIPTS/utilities/pbs_update.sh" ;; + s) exec bash "$LOCAL_SCRIPTS/menus/config_menu.sh" ;; + 0) break ;; esac done clear +msg_ok "$(translate "Thank you for using ProxMenux. Goodbye!")" diff --git a/scripts/utilities/pbs_update.sh b/scripts/utilities/pbs_update.sh index 05a453eb..608440b9 100644 --- a/scripts/utilities/pbs_update.sh +++ b/scripts/utilities/pbs_update.sh @@ -12,27 +12,30 @@ if ! pmx_is_pbs || [[ "$(pmx_platform_field supported)" != true ]]; then exit 1 fi [[ $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 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.')" - read -r _ + msg_success "$(translate "Press Enter to continue...")" + read -r exit 1 fi plan=$(mktemp) trap 'rm -f "$plan"' EXIT 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 fi -dialog --backtitle "ProxMenux · PBS" --title "$(translate 'Review package upgrade')" --textbox "$plan" 24 100 -dialog --defaultno --title "$(translate 'Apply PBS package upgrade')" \ +dialog --backtitle "ProxMenux" --title "$(translate 'Review package upgrade')" --textbox "$plan" 24 100 +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 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.')" else 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 fi -read -r _ +msg_success "$(translate "Press Enter to continue...")" +read -r