From 9a36f5df08d6318b8b8eabe188d14094f75339c1 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Mon, 9 Feb 2026 08:58:33 +0100 Subject: [PATCH] feat(unattended): handle whiptail menus and disabled scripts in silent mode Add phs_whiptail() wrapper function to build.func that transparently handles whiptail dialogs in unattended/silent mode (PHS_SILENT=1): - radiolist: auto-selects the ON (default) option - menu: auto-selects the first option (typically 'Update') - yesno: auto-confirms (returns 0) - msgbox: auto-acknowledges (returns 0) - passwordbox/inputbox: signals skip (returns 1) Replace all whiptail calls in update_script() functions across 19 ct scripts with phs_whiptail for unattended compatibility. Affected scripts: - alpine-docker, alpine-grafana, alpine-loki, alpine-nextcloud - alpine-redis, alpine-valkey, alpine-vaultwarden, alpine-zigbee2mqtt - alpine, cronicle, gitea-mirror, homeassistant - loki, meilisearch, node-red, npmplus - plex, podman-homeassistant, vaultwarden Also improve update-apps.sh batch updater: - Exit code 75 (EX_TEMPFAIL) = disabled/skipped, not a failure - In unattended mode, failed containers are skipped instead of aborting the entire update loop - Update nginxproxymanager.sh to use exit 75 for disabled state Closes #11620 --- ct/alpine-docker.sh | 2 +- ct/alpine-grafana.sh | 2 +- ct/alpine-loki.sh | 2 +- ct/alpine-nextcloud.sh | 2 +- ct/alpine-redis.sh | 2 +- ct/alpine-valkey.sh | 2 +- ct/alpine-vaultwarden.sh | 4 +- ct/alpine-zigbee2mqtt.sh | 2 +- ct/alpine.sh | 2 +- ct/cronicle.sh | 2 +- ct/gitea-mirror.sh | 6 +-- ct/homeassistant.sh | 2 +- ct/loki.sh | 2 +- ct/meilisearch.sh | 2 +- ct/nginxproxymanager.sh | 2 +- ct/node-red.sh | 4 +- ct/npmplus.sh | 2 +- ct/plex.sh | 2 +- ct/podman-homeassistant.sh | 2 +- ct/vaultwarden.sh | 4 +- misc/build.func | 106 +++++++++++++++++++++++++++++++++++++ tools/pve/update-apps.sh | 12 +++++ 22 files changed, 143 insertions(+), 25 deletions(-) diff --git a/ct/alpine-docker.sh b/ct/alpine-docker.sh index 698139f16..12900ee33 100644 --- a/ct/alpine-docker.sh +++ b/ct/alpine-docker.sh @@ -25,7 +25,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ "1" "Check for Docker Updates" 3>&2 2>&1 1>&3 ) exit_status=$? diff --git a/ct/alpine-grafana.sh b/ct/alpine-grafana.sh index 2126ecb9b..e777dc3d2 100644 --- a/ct/alpine-grafana.sh +++ b/ct/alpine-grafana.sh @@ -26,7 +26,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ "1" "Check for Grafana Updates" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/alpine-loki.sh b/ct/alpine-loki.sh index 057506689..d312d8a15 100644 --- a/ct/alpine-loki.sh +++ b/ct/alpine-loki.sh @@ -26,7 +26,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ "1" "Check for Loki Updates" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/alpine-nextcloud.sh b/ct/alpine-nextcloud.sh index a0e8c5f68..debd0ca3c 100644 --- a/ct/alpine-nextcloud.sh +++ b/ct/alpine-nextcloud.sh @@ -28,7 +28,7 @@ function update_script() { apk add -q newt fi while true; do - CHOICE=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + CHOICE=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "Nextcloud Login Credentials" ON \ "2" "Renew Self-signed Certificate" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/alpine-redis.sh b/ct/alpine-redis.sh index 214bb20d5..afe477c85 100644 --- a/ct/alpine-redis.sh +++ b/ct/alpine-redis.sh @@ -26,7 +26,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "Redis Management" --menu "Select option" 11 58 3 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "Redis Management" --menu "Select option" 11 58 3 \ "1" "Update Redis" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/alpine-valkey.sh b/ct/alpine-valkey.sh index 131ae581d..6b7e43682 100644 --- a/ct/alpine-valkey.sh +++ b/ct/alpine-valkey.sh @@ -26,7 +26,7 @@ function update_script() { LXCIP=$(ip a s dev eth0 | awk '/inet / {print $2}' | cut -d/ -f1) while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "Valkey Management" --menu "Select option" 11 58 3 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "Valkey Management" --menu "Select option" 11 58 3 \ "1" "Update Valkey" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LXCIP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/alpine-vaultwarden.sh b/ct/alpine-vaultwarden.sh index 5f01700d5..e7e2be7d0 100644 --- a/ct/alpine-vaultwarden.sh +++ b/ct/alpine-vaultwarden.sh @@ -25,7 +25,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 2 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 2 \ "1" "Update Vaultwarden" \ "2" "Reset ADMIN_TOKEN" 3>&2 2>&1 1>&3 ) @@ -43,7 +43,7 @@ function update_script() { exit ;; 2) - if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then + if NEWTOKEN=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Setup your ADMIN_TOKEN (make it strong)" 10 58 3>&1 1>&2 2>&3); then if [[ -z "$NEWTOKEN" ]]; then exit-script; fi if ! command -v argon2 >/dev/null 2>&1; then apk add argon2 &>/dev/null; fi TOKEN=$(echo -n "${NEWTOKEN}" | argon2 "$(openssl rand -base64 32)" -e -id -k 19456 -t 2 -p 1) diff --git a/ct/alpine-zigbee2mqtt.sh b/ct/alpine-zigbee2mqtt.sh index ab2c2ceea..ce4e36f6c 100644 --- a/ct/alpine-zigbee2mqtt.sh +++ b/ct/alpine-zigbee2mqtt.sh @@ -25,7 +25,7 @@ function update_script() { fi while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 1 \ "1" "Check for Zigbee2MQTT Updates" 3>&2 2>&1 1>&3 ) exit_status=$? diff --git a/ct/alpine.sh b/ct/alpine.sh index 5aa8111f5..40b363ac8 100644 --- a/ct/alpine.sh +++ b/ct/alpine.sh @@ -21,7 +21,7 @@ catch_errors function update_script() { UPD=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 1 \ "1" "Check for Alpine Updates" ON \ 3>&1 1>&2 2>&3 ) diff --git a/ct/cronicle.sh b/ct/cronicle.sh index 61847011f..b085fb089 100644 --- a/ct/cronicle.sh +++ b/ct/cronicle.sh @@ -23,7 +23,7 @@ function update_script() { header_info check_container_storage check_container_resources - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install ${APP} Worker" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/gitea-mirror.sh b/ct/gitea-mirror.sh index 65a84f479..8a107c1b1 100644 --- a/ct/gitea-mirror.sh +++ b/ct/gitea-mirror.sh @@ -31,17 +31,17 @@ function update_script() { APP_VERSION=$(grep -o '"version": *"[^"]*"' /opt/gitea-mirror/package.json | cut -d'"' -f4) if [[ $APP_VERSION =~ ^2\. ]]; then - if ! whiptail --backtitle "Gitea Mirror Update" --title "⚠️ VERSION 2.x DETECTED" --yesno \ + if ! phs_whiptail --backtitle "Gitea Mirror Update" --title "⚠️ VERSION 2.x DETECTED" --yesno \ "WARNING: Version $APP_VERSION detected!\n\nUpdating from version 2.x will CLEAR ALL CONFIGURATION.\n\nThis includes:\n• API tokens\n• User settings\n• Repository configurations\n• All custom settings\n\nDo you want to continue with the update process?" 15 70 --defaultno; then exit 0 fi - if ! whiptail --backtitle "Gitea Mirror Update" --title "⚠️ FINAL CONFIRMATION" --yesno \ + if ! phs_whiptail --backtitle "Gitea Mirror Update" --title "⚠️ FINAL CONFIRMATION" --yesno \ "FINAL WARNING: This update WILL clear all configuration!\n\nBEFORE PROCEEDING, please:\n\n• Copy API tokens to a safe location\n• Backup any custom configurations\n• Note down repository settings\n\nThis action CANNOT be undone!" 18 70 --defaultno; then whiptail --backtitle "Gitea Mirror Update" --title "Update Cancelled" --msgbox "Update process cancelled. Please backup your configuration before proceeding." 8 60 exit 0 fi - whiptail --backtitle "Gitea Mirror Update" --title "Proceeding with Update" --msgbox \ + phs_whiptail --backtitle "Gitea Mirror Update" --title "Proceeding with Update" --msgbox \ "Proceeding with version $APP_VERSION update.\n\nAll configuration will be cleared as warned." 8 50 rm -rf /opt/gitea-mirror fi diff --git a/ct/homeassistant.sh b/ct/homeassistant.sh index 4a91af857..ae0e1dc89 100644 --- a/ct/homeassistant.sh +++ b/ct/homeassistant.sh @@ -27,7 +27,7 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update ALL Containers" ON \ "2" "Remove ALL Unused Images" OFF \ "3" "Install HACS" OFF \ diff --git a/ct/loki.sh b/ct/loki.sh index cd9c5869e..413895c1e 100644 --- a/ct/loki.sh +++ b/ct/loki.sh @@ -31,7 +31,7 @@ function update_script() { while true; do CHOICE=$( - whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ + phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --menu "Select option" 11 58 3 \ "1" "Update Loki & Promtail" \ "2" "Allow 0.0.0.0 for listening" \ "3" "Allow only ${LOCAL_IP} for listening" 3>&2 2>&1 1>&3 diff --git a/ct/meilisearch.sh b/ct/meilisearch.sh index dc5e866d9..f26bf529b 100644 --- a/ct/meilisearch.sh +++ b/ct/meilisearch.sh @@ -24,7 +24,7 @@ function update_script() { check_container_storage check_container_resources - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "Meilisearch Update" --radiolist --cancel-button Exit-Script "Spacebar = Select" 10 58 2 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "Meilisearch Update" --radiolist --cancel-button Exit-Script "Spacebar = Select" 10 58 2 \ "1" "Update Meilisearch" ON \ "2" "Update Meilisearch-UI" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/nginxproxymanager.sh b/ct/nginxproxymanager.sh index 8abb75738..bace992c9 100644 --- a/ct/nginxproxymanager.sh +++ b/ct/nginxproxymanager.sh @@ -32,7 +32,7 @@ function update_script() { msg_error "The repository's GPG key uses SHA-1 signatures, which are no longer accepted by Debian as of February 1, 2026." msg_error "The issue is tracked in openresty/openresty#1097" msg_error "For more details, see: https://github.com/community-scripts/ProxmoxVE/issues/11406" - exit 1 + exit 75 if [[ $(grep -E '^VERSION_ID=' /etc/os-release) == *"12"* ]]; then msg_error "Wrong Debian version detected!" diff --git a/ct/node-red.sh b/ct/node-red.sh index 7a864fb69..8175219cd 100644 --- a/ct/node-red.sh +++ b/ct/node-red.sh @@ -27,7 +27,7 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 2 \ "1" "Update ${APP}" ON \ "2" "Install Themes" OFF \ 3>&1 1>&2 2>&3) @@ -49,7 +49,7 @@ function update_script() { exit fi if [ "$UPD" == "2" ]; then - THEME=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ + THEME=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "NODE-RED THEMES" --radiolist --cancel-button Exit-Script "Choose Theme" 15 58 6 \ "aurora" "" OFF \ "cobalt2" "" OFF \ "dark" "" OFF \ diff --git a/ct/npmplus.sh b/ct/npmplus.sh index d9a0376ca..71ff52be0 100644 --- a/ct/npmplus.sh +++ b/ct/npmplus.sh @@ -20,7 +20,7 @@ color catch_errors function update_script() { - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE MODE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 14 60 2 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE MODE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 14 60 2 \ "1" "Check for Alpine Updates" OFF \ "2" "Update NPMplus Docker Container" ON \ 3>&1 1>&2 2>&3) diff --git a/ct/plex.sh b/ct/plex.sh index e36f313c5..ec67546b4 100644 --- a/ct/plex.sh +++ b/ct/plex.sh @@ -29,7 +29,7 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select \nplexupdate info >> https://github.com/mrworf/plexupdate" 10 59 2 \ "1" "Update LXC" ON \ "2" "Install plexupdate" OFF \ 3>&1 1>&2 2>&3) diff --git a/ct/podman-homeassistant.sh b/ct/podman-homeassistant.sh index bdedb0c5b..88193751c 100644 --- a/ct/podman-homeassistant.sh +++ b/ct/podman-homeassistant.sh @@ -27,7 +27,7 @@ function update_script() { msg_error "No ${APP} Installation Found!" exit fi - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "UPDATE" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 4 \ "1" "Update system and containers" ON \ "2" "Install HACS" OFF \ "3" "Install FileBrowser" OFF \ diff --git a/ct/vaultwarden.sh b/ct/vaultwarden.sh index ee7751176..a3e11748d 100644 --- a/ct/vaultwarden.sh +++ b/ct/vaultwarden.sh @@ -31,7 +31,7 @@ function update_script() { VAULT=$(get_latest_github_release "dani-garcia/vaultwarden") WVRELEASE=$(get_latest_github_release "dani-garcia/bw_web_builds") - UPD=$(whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ + UPD=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --title "SUPPORT" --radiolist --cancel-button Exit-Script "Spacebar = Select" 11 58 3 \ "1" "VaultWarden $VAULT" ON \ "2" "Web-Vault $WVRELEASE" OFF \ "3" "Set Admin Token" OFF \ @@ -92,7 +92,7 @@ function update_script() { fi if [ "$UPD" == "3" ]; then - if NEWTOKEN=$(whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then + if NEWTOKEN=$(phs_whiptail --backtitle "Proxmox VE Helper Scripts" --passwordbox "Set the ADMIN_TOKEN" 10 58 3>&1 1>&2 2>&3); then if [[ -z "$NEWTOKEN" ]]; then exit; fi ensure_dependencies argon2 TOKEN=$(echo -n "${NEWTOKEN}" | argon2 "$(openssl rand -base64 32)" -t 2 -m 16 -p 4 -l 64 -e) diff --git a/misc/build.func b/misc/build.func index c4c078633..bae829702 100644 --- a/misc/build.func +++ b/misc/build.func @@ -3326,6 +3326,112 @@ configure_ssh_settings() { # - In silent mode: runs update_script with automatic cleanup # - Otherwise: shows update/setting menu and runs update_script with cleanup # ------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ +# phs_whiptail() +# +# Drop-in wrapper for whiptail in update_script() functions. +# In silent/unattended mode (PHS_SILENT=1), returns the default option +# (the one marked "ON") without showing a dialog. +# In interactive mode, passes through to whiptail transparently. +# +# Usage: same as whiptail, e.g.: +# UPD=$(phs_whiptail --backtitle "..." --title "..." --radiolist "..." H W N \ +# "1" "Option A" ON \ +# "2" "Option B" OFF \ +# 3>&1 1>&2 2>&3) +# +# For --menu style (no ON/OFF), the first item is selected as default. +# Returns exit code 1 if no default can be determined (script should skip). +# ------------------------------------------------------------------------------ +phs_whiptail() { + if [ -z "${PHS_SILENT+x}" ] || [[ "${PHS_SILENT}" != "1" ]]; then + # Interactive mode: pass through to real whiptail + whiptail "$@" + return $? + fi + + # Silent mode: extract the default selection + local mode="" items_start=0 i=0 + local -a args=("$@") + + # Detect dialog type (--radiolist, --menu, --yesno, --passwordbox) + for ((i = 0; i < ${#args[@]}; i++)); do + case "${args[$i]}" in + --radiolist) + mode="radiolist" + ;; + --menu) + mode="menu" + ;; + --yesno) + # In silent mode, auto-confirm (return 0 = yes) + return 0 + ;; + --msgbox) + # In silent mode, skip message boxes (just acknowledge) + return 0 + ;; + --passwordbox | --inputbox) + # Cannot provide input in silent mode, signal skip + msg_warn "Interactive input required - skipping in unattended mode" + return 1 + ;; + esac + done + + if [[ "$mode" == "radiolist" ]]; then + # radiolist items are triplets: tag description ON/OFF + # Find the one marked ON + for ((i = 0; i < ${#args[@]}; i++)); do + if [[ "${args[$i]}" == "ON" ]]; then + # The tag is 2 positions before ON + echo "${args[$((i - 2))]}" + return 0 + fi + done + # No ON found, use first item after the height/width/count args + # Fall through to menu logic + mode="menu" + fi + + if [[ "$mode" == "menu" ]]; then + # menu items are pairs: tag description + # Find the first tag after height/width/menuheight (3 consecutive numbers after the prompt text) + local h_w_n_count=0 + local past_flags=0 + for ((i = 0; i < ${#args[@]}; i++)); do + # Skip option flags and their values + if [[ "${args[$i]}" == --* ]]; then + # Some flags take a value (--title, --backtitle, etc.) - skip next arg too + case "${args[$i]}" in + --title | --backtitle | --cancel-button | --ok-button | --default-item) ((i++)) ;; + esac + continue + fi + # First non-flag string is the prompt text, skip it + if [[ $past_flags -eq 0 ]]; then + past_flags=1 + continue + fi + # Next 3 numbers are height, width, menu-height + if [[ "${args[$i]}" =~ ^[0-9]+$ ]] && [[ $h_w_n_count -lt 3 ]]; then + ((h_w_n_count++)) + continue + fi + # After H W N, the next arg is the first menu tag + if [[ $h_w_n_count -ge 3 ]]; then + echo "${args[$i]}" + return 0 + fi + done + fi + + # Fallback: could not determine default + msg_warn "Cannot determine default action - skipping in unattended mode" + return 1 +} + start() { source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) if command -v pveversion >/dev/null 2>&1; then diff --git a/tools/pve/update-apps.sh b/tools/pve/update-apps.sh index 71d7fcdb0..d7981587b 100644 --- a/tools/pve/update-apps.sh +++ b/tools/pve/update-apps.sh @@ -421,6 +421,18 @@ for container in $CHOICE; do if [ $exit_code -eq 0 ]; then msg_ok "Updated container $container" + elif [ $exit_code -eq 75 ]; then + # Exit code 75 (EX_TEMPFAIL) = script is disabled or skipped intentionally + echo -e "${YW}[WARN]${CL} Update script for container $container is currently disabled - skipping" + # Restore build resources if changed + if [ "$UPDATE_BUILD_RESOURCES" -eq "1" ]; then + pct set "$container" --cores "$run_cpu" --memory "$run_ram" + fi + continue + elif [ "$UNATTENDED_UPDATE" == "yes" ]; then + # In unattended mode, log the failure and continue with next container + msg_error "Update failed for container $container - skipping (unattended mode)" + continue elif [ "$BACKUP_CHOICE" == "yes" ]; then msg_info "Restoring LXC from backup" pct stop $container