From 0e364adb544baa20caf8b9b87fb1f64fdcbb4025 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Tue, 24 Feb 2026 14:22:07 +0100 Subject: [PATCH] core: fix broken "command not found" after err_trap (#12280) --- misc/build.func | 34 +++++++++++++++++++++------------- misc/core.func | 15 +++++++++++++-- 2 files changed, 34 insertions(+), 15 deletions(-) diff --git a/misc/build.func b/misc/build.func index 8ee1903cd..d9929affe 100644 --- a/misc/build.func +++ b/misc/build.func @@ -38,17 +38,18 @@ # - Captures app-declared resource defaults (CPU, RAM, Disk) # ------------------------------------------------------------------------------ variables() { - NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. - var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. - INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. - PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase - DIAGNOSTICS="no" # Safe default: no telemetry until user consents via diagnostics_check() - METHOD="default" # sets the METHOD variable to "default", used for the API call. - RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. - EXECUTION_ID="${RANDOM_UUID}" # Unique execution ID for telemetry record identification (unique-indexed in PocketBase) - SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files - BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log - combined_log="/tmp/install-${SESSION_ID}-combined.log" # Combined log (build + install) for failed installations + NSAPP=$(echo "${APP,,}" | tr -d ' ') # This function sets the NSAPP variable by converting the value of the APP variable to lowercase and removing any spaces. + var_install="${NSAPP}-install" # sets the var_install variable by appending "-install" to the value of NSAPP. + INTEGER='^[0-9]+([.][0-9]+)?$' # it defines the INTEGER regular expression pattern. + PVEHOST_NAME=$(hostname) # gets the Proxmox Hostname and sets it to Uppercase + DIAGNOSTICS="no" # Safe default: no telemetry until user consents via diagnostics_check() + METHOD="default" # sets the METHOD variable to "default", used for the API call. + RANDOM_UUID="$(cat /proc/sys/kernel/random/uuid)" # generates a random UUID and sets it to the RANDOM_UUID variable. + EXECUTION_ID="${RANDOM_UUID}" # Unique execution ID for telemetry record identification (unique-indexed in PocketBase) + SESSION_ID="${RANDOM_UUID:0:8}" # Short session ID (first 8 chars of UUID) for log files + BUILD_LOG="/tmp/create-lxc-${SESSION_ID}.log" # Host-side container creation log + # NOTE: combined_log is constructed locally in build_container() and ensure_log_on_host() + # as "/tmp/${NSAPP}-${CTID}-${SESSION_ID}.log" (requires CTID, not available here) CTTYPE="${CTTYPE:-${CT_TYPE:-1}}" # Parse dev_mode early @@ -1850,7 +1851,7 @@ advanced_settings() { # ═══════════════════════════════════════════════════════════════════════════ # STEP 2: Root Password - # ═══════════════════════════════════════════════════════════════════════════ + # ════════════════════════════════════════════════════════════════════════���══ 2) if PW1=$(whiptail --backtitle "Proxmox VE Helper Scripts [Step $STEP/$MAX_STEP]" \ --title "ROOT PASSWORD" \ @@ -4174,6 +4175,13 @@ EOF' # Report failure to telemetry API (now with log available on host) post_update_to_api "failed" "$install_exit_code" + # Defense-in-depth: Ensure error handling stays disabled during recovery. + # Some functions (e.g. silent/$STD) unconditionally re-enable set -Eeuo pipefail + # and trap 'error_handler' ERR. If any code path above called such a function, + # the grep/sed pipelines below would trigger error_handler on non-match (exit 1). + set +Eeuo pipefail + trap - ERR + # Show combined log location if [[ -n "$CTID" && -n "${SESSION_ID:-}" ]]; then msg_custom "📋" "${YW}" "Installation log: ${combined_log}" @@ -4287,7 +4295,7 @@ EOF' if [[ "$is_cmd_not_found" == true ]]; then local missing_cmd="" if [[ -f "$combined_log" ]]; then - missing_cmd=$(grep -oiE '[a-zA-Z0-9_.-]+: command not found' "$combined_log" | tail -1 | sed 's/: command not found//') + missing_cmd=$(grep -oiE '[a-zA-Z0-9_.-]+: command not found' "$combined_log" 2>/dev/null | tail -1 | sed 's/: command not found//') || true fi if [[ -n "$missing_cmd" ]]; then echo -e "${TAB}${INFO} Missing command: ${GN}${missing_cmd}${CL}" diff --git a/misc/core.func b/misc/core.func index c0460c0ff..0d203a77b 100644 --- a/misc/core.func +++ b/misc/core.func @@ -490,6 +490,8 @@ log_section() { # - Executes command with output redirected to active log file # - On error: displays last 20 lines of log and exits with original exit code # - Temporarily disables error trap to capture exit code correctly +# - Saves and restores previous error handling state (so callers that +# intentionally disabled error handling aren't silently re-enabled) # - Sources explain_exit_code() for detailed error messages # ------------------------------------------------------------------------------ silent() { @@ -507,14 +509,23 @@ silent() { return 0 fi + # Save current error handling state before disabling + # This prevents re-enabling error handling when the caller intentionally + # disabled it (e.g. build_container recovery section) + local _restore_errexit=false + [[ "$-" == *e* ]] && _restore_errexit=true + set +Eeuo pipefail trap - ERR "$@" >>"$logfile" 2>&1 local rc=$? - set -Eeuo pipefail - trap 'error_handler' ERR + # Restore error handling ONLY if it was active before this call + if $_restore_errexit; then + set -Eeuo pipefail + trap 'error_handler' ERR + fi if [[ $rc -ne 0 ]]; then # Source explain_exit_code if needed