From f07f2cb04e88c4f15fe6267cb8ce143f5bd3e54b Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Tue, 17 Feb 2026 13:25:17 +0100 Subject: [PATCH] core: error-handler improvements | better exit_code handling | better tools.func source check (#12019) * core: add progress; fix exit status Introduce post_progress_to_api() in alpine-install.func and install.func to send a lightweight, fire-and-forget telemetry ping (HTTP POST) that updates an existing telemetry record to "configuring" when DIAGNOSTICS=yes and RANDOM_UUID is set. The function is non-blocking (curl -m 5, errors ignored) and is invoked during container setup and after OS updates to signal active progress. Also adjust api_exit_script() in build.func to report success (post_update_to_api "done" "0") for cases where the script exited normally but a completion status wasn't posted, instead of reporting failure. * Safer tools.func load and improved error handling Replace process-substitution sourcing of tools.func with an explicit curl -> variable -> source via /dev/stdin, adding failure messages and a check that expected functions (e.g. fetch_and_deploy_gh_release) are present (misc/alpine-install.func, misc/install.func). Add categorize_error mapping for exit code 10 -> "config" (misc/api.func). Tweak build.func: minor pipeline formatting and change the ERR trap to capture the actual exit code and only call ensure_log_on_host/post_update on non-zero exits, preventing erroneous failure reporting. --- misc/alpine-install.func | 32 +++++++++++++++++++++++++++++++- misc/api.func | 3 +++ misc/build.func | 6 +++--- misc/install.func | 32 +++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/misc/alpine-install.func b/misc/alpine-install.func index 537a3148e..49b83dbae 100644 --- a/misc/alpine-install.func +++ b/misc/alpine-install.func @@ -14,6 +14,25 @@ catch_errors # Get LXC IP address (must be called INSIDE container, after network is up) get_lxc_ip +# ------------------------------------------------------------------------------ +# post_progress_to_api() +# +# - Lightweight progress ping from inside the container +# - Updates the existing telemetry record status from "installing" to "configuring" +# - Signals that the installation is actively progressing (not stuck) +# - Fire-and-forget: never blocks or fails the script +# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set +# ------------------------------------------------------------------------------ +post_progress_to_api() { + command -v curl &>/dev/null || return 0 + [[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0 + [[ -z "${RANDOM_UUID:-}" ]] && return 0 + + curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \ + -H "Content-Type: application/json" \ + -d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true +} + # This function enables IPv6 if it's not disabled and sets verbose mode verb_ip6() { set_std_mode # Set STD mode based on VERBOSE @@ -53,6 +72,7 @@ setting_up_container() { fi msg_ok "Set up Container OS" msg_ok "Network Connected: ${BL}$(ip addr show | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1 | tail -n1)${CL}" + post_progress_to_api } # This function checks the network connection by pinging a known IP address and prompts the user to continue if the internet is not connected @@ -85,8 +105,18 @@ network_check() { update_os() { msg_info "Updating Container OS" $STD apk -U upgrade - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) + local tools_content + tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || { + msg_error "Failed to download tools.func" + exit 6 + } + source /dev/stdin <<<"$tools_content" + if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then + msg_error "tools.func loaded but incomplete — missing expected functions" + exit 6 + fi msg_ok "Updated Container OS" + post_progress_to_api } # This function modifies the message of the day (motd) and SSH settings diff --git a/misc/api.func b/misc/api.func index 087f80ec1..baef2a1ad 100644 --- a/misc/api.func +++ b/misc/api.func @@ -908,6 +908,9 @@ categorize_error() { # Network errors (curl/wget) 6 | 7 | 22 | 35) echo "network" ;; + # Docker / Privileged mode required + 10) echo "config" ;; + # Timeout errors 28 | 124 | 211) echo "timeout" ;; diff --git a/misc/build.func b/misc/build.func index 7636c4671..b0d7afbee 100644 --- a/misc/build.func +++ b/misc/build.func @@ -5564,15 +5564,15 @@ api_exit_script() { post_update_to_api "failed" "$exit_code" elif [[ "${POST_TO_API_DONE:-}" == "true" && "${POST_UPDATE_DONE:-}" != "true" ]]; then # Script exited with 0 but never sent a completion status - # This catches edge cases like early returns after post_to_api() - post_update_to_api "failed" "1" + # exit_code=0 is never an error — report as success + post_update_to_api "done" "0" fi } if command -v pveversion >/dev/null 2>&1; then trap 'api_exit_script' EXIT fi -trap '_ERR_CODE=$?; ensure_log_on_host; post_update_to_api "failed" "$_ERR_CODE"' ERR +trap 'local _ec=$?; if [[ $_ec -ne 0 ]]; then ensure_log_on_host; post_update_to_api "failed" "$_ec"; fi' ERR trap 'ensure_log_on_host; post_update_to_api "failed" "129"; exit 129' SIGHUP trap 'ensure_log_on_host; post_update_to_api "failed" "130"; exit 130' SIGINT trap 'ensure_log_on_host; post_update_to_api "failed" "143"; exit 143' SIGTERM diff --git a/misc/install.func b/misc/install.func index 5a8d10d0b..ed7205c7d 100644 --- a/misc/install.func +++ b/misc/install.func @@ -40,6 +40,25 @@ catch_errors # Get LXC IP address (must be called INSIDE container, after network is up) get_lxc_ip +# ------------------------------------------------------------------------------ +# post_progress_to_api() +# +# - Lightweight progress ping from inside the container +# - Updates the existing telemetry record status from "installing" to "configuring" +# - Signals that the installation is actively progressing (not stuck) +# - Fire-and-forget: never blocks or fails the script +# - Only executes if DIAGNOSTICS=yes and RANDOM_UUID is set +# ------------------------------------------------------------------------------ +post_progress_to_api() { + command -v curl &>/dev/null || return 0 + [[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0 + [[ -z "${RANDOM_UUID:-}" ]] && return 0 + + curl -fsS -m 5 -X POST "https://telemetry.community-scripts.org/telemetry" \ + -H "Content-Type: application/json" \ + -d "{\"random_id\":\"${RANDOM_UUID}\",\"type\":\"lxc\",\"nsapp\":\"${app:-unknown}\",\"status\":\"configuring\"}" &>/dev/null || true +} + # ============================================================================== # SECTION 2: NETWORK & CONNECTIVITY # ============================================================================== @@ -103,6 +122,7 @@ setting_up_container() { msg_ok "Set up Container OS" #msg_custom "${CM}" "${GN}" "Network Connected: ${BL}$(hostname -I)" msg_ok "Network Connected: ${BL}$(hostname -I)" + post_progress_to_api } # ------------------------------------------------------------------------------ @@ -206,8 +226,18 @@ EOF $STD apt-get -o Dpkg::Options::="--force-confold" -y dist-upgrade rm -rf /usr/lib/python3.*/EXTERNALLY-MANAGED msg_ok "Updated Container OS" + post_progress_to_api - source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) + local tools_content + tools_content=$(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/tools.func) || { + msg_error "Failed to download tools.func" + exit 6 + } + source /dev/stdin <<<"$tools_content" + if ! declare -f fetch_and_deploy_gh_release >/dev/null 2>&1; then + msg_error "tools.func loaded but incomplete — missing expected functions" + exit 6 + fi } # ==============================================================================