Compare commits

...

3 Commits

Author SHA1 Message Date
CanbiZ (MickLesk)
2864da08d1 wrong branhc, revert 2026-02-09 09:15:19 +01:00
CanbiZ (MickLesk)
9f853b5750 Update nginxproxymanager.sh 2026-02-09 09:14:32 +01:00
CanbiZ (MickLesk)
9a36f5df08 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
2026-02-09 08:58:33 +01:00
21 changed files with 142 additions and 24 deletions

View File

@@ -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=$?

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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=$?

View File

@@ -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
)

View File

@@ -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)

View File

@@ -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

View File

@@ -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 \

View File

@@ -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

View File

@@ -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)

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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)

View File

@@ -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 \

View File

@@ -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)

View File

@@ -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

View File

@@ -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