Compare commits

...

4 Commits

Author SHA1 Message Date
github-actions[bot]
96d1008e44 chore: update github-versions.json 2026-02-13 18:14:00 +00:00
CanbiZ (MickLesk)
0957a23366 JSON-escape CPU and GPU model strings
Apply json_escape to GPU_MODEL and CPU_MODEL before assigning to gpu_model and cpu_model to ensure values are safe for inclusion in API JSON payloads. Updated in post_to_api, post_to_api_vm, and post_update_to_api; variable declarations were adjusted to call json_escape on the existing environment values (fallbacks unchanged). This prevents raw model strings from breaking the API payload.
2026-02-13 14:18:36 +01:00
community-scripts-pr-app[bot]
9f3588dd8d Update CHANGELOG.md (#11886)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-02-13 12:50:14 +00:00
CanbiZ (MickLesk)
f23414a1a8 Retry reporting with fallback payloads (#11885)
Enhance post_update_to_api to support a "force" mode and robust retry logic: add a 3rd-arg bypass to duplicate suppression, capture a short error summary, and perform up to three POST attempts (full payload, shortened error payload, minimal payload) with HTTP code checks and small backoffs. Mark POST_UPDATE_DONE on success (or after three attempts) to avoid infinite retries. Also invoke post_update_to_api with the "force" flag from cleanup paths in build.func and error_handler.func so a final status update is attempted after cleanup.
2026-02-13 13:49:49 +01:00
5 changed files with 124 additions and 27 deletions

View File

@@ -417,6 +417,12 @@ Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit
- chore(donetick): add config entry for v0.1.73 [@tomfrenzel](https://github.com/tomfrenzel) ([#11872](https://github.com/community-scripts/ProxmoxVE/pull/11872))
- Refactor: Radicale [@vhsdream](https://github.com/vhsdream) ([#11850](https://github.com/community-scripts/ProxmoxVE/pull/11850))
### 💾 Core
- #### 🔧 Refactor
- core: retry reporting with fallback payloads [@MickLesk](https://github.com/MickLesk) ([#11885](https://github.com/community-scripts/ProxmoxVE/pull/11885))
### 📡 API
- #### ✨ New Features

View File

@@ -1,5 +1,5 @@
{
"generated": "2026-02-13T12:11:36Z",
"generated": "2026-02-13T18:13:59Z",
"versions": [
{
"slug": "2fauth",
@@ -67,9 +67,9 @@
{
"slug": "autobrr",
"repo": "autobrr/autobrr",
"version": "v1.72.1",
"version": "v1.73.0",
"pinned": false,
"date": "2026-01-30T12:57:58Z"
"date": "2026-02-13T16:37:28Z"
},
{
"slug": "autocaliweb",
@@ -445,9 +445,9 @@
{
"slug": "gotify",
"repo": "gotify/server",
"version": "v2.8.0",
"version": "v2.9.0",
"pinned": false,
"date": "2026-01-02T11:56:16Z"
"date": "2026-02-13T15:22:31Z"
},
{
"slug": "grist",
@@ -823,9 +823,9 @@
{
"slug": "metube",
"repo": "alexta69/metube",
"version": "2026.02.12",
"version": "2026.02.13",
"pinned": false,
"date": "2026-02-12T21:05:49Z"
"date": "2026-02-13T15:18:17Z"
},
{
"slug": "miniflux",
@@ -1411,9 +1411,9 @@
{
"slug": "tandoor",
"repo": "TandoorRecipes/recipes",
"version": "2.5.0",
"version": "2.5.1",
"pinned": false,
"date": "2026-02-08T13:23:02Z"
"date": "2026-02-13T15:57:27Z"
},
{
"slug": "tasmoadmin",
@@ -1467,9 +1467,9 @@
{
"slug": "tianji",
"repo": "msgbyte/tianji",
"version": "v1.31.12",
"version": "v1.31.13",
"pinned": false,
"date": "2026-02-12T19:06:14Z"
"date": "2026-02-13T16:30:09Z"
},
{
"slug": "traccar",
@@ -1516,9 +1516,9 @@
{
"slug": "tududi",
"repo": "chrisvel/tududi",
"version": "v0.88.4",
"version": "v0.88.5",
"pinned": false,
"date": "2026-01-20T15:11:58Z"
"date": "2026-02-13T13:54:14Z"
},
{
"slug": "tunarr",
@@ -1565,9 +1565,9 @@
{
"slug": "uptimekuma",
"repo": "louislam/uptime-kuma",
"version": "2.1.0",
"version": "2.1.1",
"pinned": false,
"date": "2026-02-07T02:31:49Z"
"date": "2026-02-13T16:07:33Z"
},
{
"slug": "vaultwarden",

View File

@@ -422,7 +422,8 @@ post_to_api() {
detect_gpu
fi
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model="${GPU_MODEL:-}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Detect CPU if not already set
@@ -430,7 +431,8 @@ post_to_api() {
detect_cpu
fi
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model="${CPU_MODEL:-}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
# Detect RAM if not already set
if [[ -z "${RAM_SPEED:-}" ]]; then
@@ -521,7 +523,8 @@ post_to_api_vm() {
detect_gpu
fi
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model="${GPU_MODEL:-}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Detect CPU if not already set
@@ -529,7 +532,8 @@ post_to_api_vm() {
detect_cpu
fi
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model="${CPU_MODEL:-}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
# Detect RAM if not already set
if [[ -z "${RAM_SPEED:-}" ]]; then
@@ -592,9 +596,12 @@ post_update_to_api() {
# Silent fail - telemetry should never break scripts
command -v curl &>/dev/null || return 0
# Prevent duplicate submissions
# Support "force" mode (3rd arg) to bypass duplicate check for retries after cleanup
local force="${3:-}"
POST_UPDATE_DONE=${POST_UPDATE_DONE:-false}
[[ "$POST_UPDATE_DONE" == "true" ]] && return 0
if [[ "$POST_UPDATE_DONE" == "true" && "$force" != "force" ]]; then
return 0
fi
[[ "${DIAGNOSTICS:-no}" == "no" ]] && return 0
[[ -z "${RANDOM_UUID:-}" ]] && return 0
@@ -605,12 +612,14 @@ post_update_to_api() {
# Get GPU info (if detected)
local gpu_vendor="${GPU_VENDOR:-unknown}"
local gpu_model="${GPU_MODEL:-}"
local gpu_model
gpu_model=$(json_escape "${GPU_MODEL:-}")
local gpu_passthrough="${GPU_PASSTHROUGH:-unknown}"
# Get CPU info (if detected)
local cpu_vendor="${CPU_VENDOR:-unknown}"
local cpu_model="${CPU_MODEL:-}"
local cpu_model
cpu_model=$(json_escape "${CPU_MODEL:-}")
# Get RAM info (if detected)
local ram_speed="${RAM_SPEED:-}"
@@ -632,6 +641,7 @@ post_update_to_api() {
esac
# For failed/unknown status, resolve exit code and error description
local short_error=""
if [[ "$pb_status" == "failed" ]] || [[ "$pb_status" == "unknown" ]]; then
if [[ "$raw_exit_code" =~ ^[0-9]+$ ]]; then
exit_code="$raw_exit_code"
@@ -645,6 +655,7 @@ post_update_to_api() {
else
error=$(json_escape "$(explain_exit_code "$exit_code")")
fi
short_error=$(json_escape "$(explain_exit_code "$exit_code")")
error_category=$(categorize_error "$exit_code")
[[ -z "$error" ]] && error="Unknown error"
fi
@@ -661,8 +672,9 @@ post_update_to_api() {
pve_version=$(pveversion 2>/dev/null | awk -F'[/ ]' '{print $2}') || true
fi
# Full payload including all fields - allows record creation if initial call failed
# The Go service will find the record by random_id and PATCH, or create if not found
local http_code=""
# ── Attempt 1: Full payload with complete error text ──
local JSON_PAYLOAD
JSON_PAYLOAD=$(
cat <<EOF
@@ -694,11 +706,80 @@ post_update_to_api() {
EOF
)
# Fire-and-forget: never block, never fail
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# ── Attempt 2: Short error text (no full log) ──
sleep 1
local RETRY_PAYLOAD
RETRY_PAYLOAD=$(
cat <<EOF
{
"random_id": "${RANDOM_UUID}",
"type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}",
"ct_type": ${CT_TYPE:-1},
"disk_size": ${DISK_SIZE:-0},
"core_count": ${CORE_COUNT:-0},
"ram_size": ${RAM_SIZE:-0},
"os_type": "${var_os:-}",
"os_version": "${var_version:-}",
"pve_version": "${pve_version}",
"method": "${METHOD:-default}",
"exit_code": ${exit_code},
"error": "${short_error}",
"error_category": "${error_category}",
"install_duration": ${duration},
"cpu_vendor": "${cpu_vendor}",
"cpu_model": "${cpu_model}",
"gpu_vendor": "${gpu_vendor}",
"gpu_model": "${gpu_model}",
"gpu_passthrough": "${gpu_passthrough}",
"ram_speed": "${ram_speed}",
"repo_source": "${REPO_SOURCE}"
}
EOF
)
http_code=$(curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$RETRY_PAYLOAD" -o /dev/null 2>/dev/null) || http_code="000"
if [[ "$http_code" =~ ^2[0-9]{2}$ ]]; then
POST_UPDATE_DONE=true
return 0
fi
# ── Attempt 3: Minimal payload (bare minimum to set status) ──
sleep 2
local MINIMAL_PAYLOAD
MINIMAL_PAYLOAD=$(
cat <<EOF
{
"random_id": "${RANDOM_UUID}",
"type": "${TELEMETRY_TYPE:-lxc}",
"nsapp": "${NSAPP:-unknown}",
"status": "${pb_status}",
"exit_code": ${exit_code},
"error": "${short_error}",
"error_category": "${error_category}",
"install_duration": ${duration}
}
EOF
)
curl -sS -w "%{http_code}" -m "${TELEMETRY_TIMEOUT}" -X POST "${TELEMETRY_URL}" \
-H "Content-Type: application/json" \
-d "$JSON_PAYLOAD" -o /dev/null 2>&1 || true
-d "$MINIMAL_PAYLOAD" -o /dev/null 2>/dev/null || true
# Tried 3 times - mark as done regardless to prevent infinite loops
POST_UPDATE_DONE=true
}

View File

@@ -4130,6 +4130,10 @@ EOF'
echo -e "${BFR}${CM}${GN}Container ${CTID} removed${CL}"
fi
# Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
post_update_to_api "failed" "$install_exit_code" "force"
exit $install_exit_code
fi
}

View File

@@ -222,6 +222,12 @@ error_handler() {
pct destroy "$CTID" &>/dev/null || true
echo -e "${GN}${CL} Container ${CTID} removed"
fi
# Force one final status update attempt after cleanup
# This ensures status is updated even if the first attempt failed (e.g., HTTP 400)
if declare -f post_update_to_api &>/dev/null; then
post_update_to_api "failed" "$exit_code" "force"
fi
fi
fi
fi