diff --git a/api/exitcodes.func b/api/exitcodes.func index f18c15b..be1c6c8 100644 --- a/api/exitcodes.func +++ b/api/exitcodes.func @@ -10,8 +10,15 @@ # function name or behaviour changed with it. # # Turns a numeric exit status into a sentence, and sorts it into a category -# for the telemetry field. Almost entirely a lookup table -- keep it in step -# with docs/exit_codes.md, which has drifted from it before. +# for the telemetry field. Almost entirely a lookup table, and the authoritative +# copy of it. +# +# Two things have to move with it. core/error_handler.func carries a fallback +# table for the container case, where this file is not loaded; and the aborted +# branch of post_update_to_api has to agree with the user_aborted codes below, +# or a run is filed as one thing and described as another. The pointer here used +# to name docs/exit_codes.md, which does not exist. + # ============================================================================== [[ -n "${_API_EXITCODES_LOADED:-}" ]] && return 0 @@ -165,6 +172,15 @@ explain_exit_code() { 192) echo "MongoDB: Database not found" ;; 193) echo "MongoDB: Fatal query error" ;; + # --- Engine (199) --- + # Not a failure of the install. It means the engine reported a terminal status + # without a code to go with it -- the flag file was unreadable, or a caller + # passed nothing. It used to be reported as 1, which is also what bash returns + # for any ordinary command failure, so a lost code and a real general error + # were the same number. + + 199) echo "Engine: exit code not reported" ;; + # --- Proxmox Custom Codes (200-231) --- 200) echo "Proxmox: Failed to create lock file" ;; 203) echo "Proxmox: Missing CTID variable" ;; @@ -263,7 +279,10 @@ categorize_error() { 150 | 151 | 153 | 154) echo "service" ;; 170 | 171 | 172 | 173 | 180 | 181 | 182 | 183 | 190 | 191 | 192 | 193) echo "database" ;; 243 | 245 | 246 | 247 | 248 | 249) echo "runtime" ;; - 129 | 130 | 143) echo "user_aborted" ;; + # Kept in step with the aborted branch of post_update_to_api: a code that + # makes the run "aborted" must not describe itself as something else here. + + 113 | 114 | 122 | 129 | 130 | 143 | 253 | 254) echo "user_aborted" ;; 134 | 137) echo "resource" ;; 139 | 141) echo "signal" ;; 1 | 2) echo "shell" ;; diff --git a/api/sysinfo.func b/api/sysinfo.func index efd35e6..13715a6 100644 --- a/api/sysinfo.func +++ b/api/sysinfo.func @@ -92,8 +92,17 @@ detect_repo_source() { REPO_SOURCE="ProxmoxVED" REPO_SLUG="community-scripts/ProxmoxVED" ;; - "") - # No URL detected — hardcoded fallback (CI rewrites VED → VE on promotion) + "" | community-scripts/core) + # No script repo identified — hardcoded fallback (CI rewrites VED → VE on + # promotion). + # + # core lands here rather than in the fork branch below. The bootstrap line + # names the engine, not the repo the ct/ script came from, so the scraping + # above finds "community-scripts/core" for every run where + # COMMUNITY_SCRIPTS_URL was not set. That is not a fork, and filing it as + # one attributed thousands of official runs to "external" and gave the + # slug its own row on the dashboard, second only to ProxmoxVE. + REPO_SOURCE="ProxmoxVED" REPO_SLUG="community-scripts/ProxmoxVED" ;; diff --git a/api/telemetry.func b/api/telemetry.func index d6a6b9e..1d9fd3e 100644 --- a/api/telemetry.func +++ b/api/telemetry.func @@ -313,7 +313,12 @@ post_update_to_api() { command -v curl &>/dev/null || return 0 local status="${1:-failed}" - local raw_exit_code="${2:-1}" + # Deliberately not defaulted to 1. A caller with nothing to report and a + # caller reporting a genuine general error are different facts, and 1 is what + # bash returns for every ordinary command failure -- defaulting to it made + # the two indistinguishable in the data. + + local raw_exit_code="${2-}" local force="${3:-}" POST_UPDATE_DONE=${POST_UPDATE_DONE:-false} @@ -336,7 +341,11 @@ post_update_to_api() { elif [[ "$raw_exit_code" == "none" ]]; then exit_code=0 else - exit_code=1 + # Neither a number nor "none": the code was never passed, or was lost on + # the way up. 199 says exactly that, where 1 used to claim a general error + # the engine never observed. + + exit_code=199 fi local pb_status error_raw="" @@ -349,9 +358,15 @@ post_update_to_api() { pb_status="aborted" ;; failed) - # Signal-based exits are user aborts, not installation failures + # Codes the engine raises when the person at the keyboard said no. A signal + # is the obvious case; 113, 114, 122 and 254 are the engine asking a + # question and being told no, and 253 is an update the user declined to + # migrate. Filing those as failures put user decisions in the failure rate: + # "exit 113" was one of the largest single signatures on the dashboard, + # sitting under exit code 1 in category "shell". + case "$exit_code" in - 129 | 130 | 143) pb_status="aborted" ;; + 113 | 114 | 122 | 129 | 130 | 143 | 253 | 254) pb_status="aborted" ;; *) pb_status="failed" ;; esac ;; diff --git a/core/error_handler.func b/core/error_handler.func index 547b40e..23e4117 100644 --- a/core/error_handler.func +++ b/core/error_handler.func @@ -155,6 +155,7 @@ if ! declare -f explain_exit_code &>/dev/null; then 191) echo "MongoDB: Authentication failed (bad user/password)" ;; 192) echo "MongoDB: Database not found" ;; 193) echo "MongoDB: Fatal query error" ;; + 199) echo "Engine: exit code not reported" ;; 200) echo "Proxmox: Failed to create lock file" ;; 203) echo "Proxmox: Missing CTID variable" ;; 204) echo "Proxmox: Missing PCT_OSTYPE variable" ;; diff --git a/lib/API.txt b/lib/API.txt index d1439e0..adf6d9a 100644 --- a/lib/API.txt +++ b/lib/API.txt @@ -30,6 +30,7 @@ _setup_intel_arc _setup_intel_legacy _setup_intel_modern _setup_mariadb_runtime_dir +_setup_npm _setup_nvidia_gpu _setup_rocm _tools_cleanup_temp_dirs diff --git a/pve/backend.func b/pve/backend.func index dde65c2..ce3718a 100644 --- a/pve/backend.func +++ b/pve/backend.func @@ -1208,7 +1208,13 @@ PROFILE if [[ -n "${SESSION_ID:-}" ]]; then local error_flag="/root/.install-${SESSION_ID}.failed" if pct exec "$CTID" -- test -f "$error_flag" 2>/dev/null; then - install_exit_code=$(pct exec "$CTID" -- cat "$error_flag" 2>/dev/null || echo "1") + # The flag holds the container's own code. When it cannot be read, or + # comes back as something that is not a number, fall back to what + # lxc-attach returned rather than to 1: that is a code we actually + # observed, and it is already in hand a few lines up. + + install_exit_code=$(pct exec "$CTID" -- cat "$error_flag" 2>/dev/null | tr -d '[:space:]') || true + [[ "$install_exit_code" =~ ^[0-9]+$ ]] || install_exit_code="${lxc_exit:-199}" pct exec "$CTID" -- rm -f "$error_flag" 2>/dev/null || true fi fi