core-refactor: single-reporter telemetry rewrite (#15933)

Overhaul the telemetry system to enforce a single-reporter model where only the HOST sends terminal statuses (success/failed/aborted) to the API. Containers now write local artifact files (.failed flag + .errinfo) that the host picks up after lxc-attach returns, preventing the race condition where a metadata-less container payload would win over the full host payload.

Key changes:
- Add TELEMETRY_CONTEXT=container export in install.func/alpine-install.func to mark container context before error handling starts
- Introduce _is_container_context() heuristic and _container_write_failure() artifact writer in error_handler.func
- Refactor api.func: unified _tm_payload() builder (full metadata on every send), _tm_send() curl wrapper, _tm_enabled() gate, telemetry_collect_sysinfo() cached collector
- Add structured .errinfo capture in silent() (core.func) using byte-offset to extract exactly the failing command's output
- Pull .errinfo from container in build.func after lxc-attach for precise error traces
- Add categorize_error(), telemetry_new_attempt(), detect_arm(), REPO_SLUG tracking
- Signal exits (129/130/143) now report as 'aborted' instead of 'failed'
- Remove post_update_to_api_extended() (superseded by unified _tm_payload)
- Export REPO_SOURCE, REPO_SLUG, TELEMETRY_PLATFORM into container environment
This commit is contained in:
CanbiZ (MickLesk)
2026-07-20 20:32:36 +02:00
committed by GitHub
parent b889e8d05e
commit 6f04a9787f
7 changed files with 820 additions and 1055 deletions
+34
View File
@@ -4072,6 +4072,11 @@ build_container() {
export RANDOM_UUID="$RANDOM_UUID"
export EXECUTION_ID="$EXECUTION_ID"
export SESSION_ID="$SESSION_ID"
# Repo attribution + platform for container-side progress pings (the
# container inherits the host's detection instead of re-detecting)
export REPO_SOURCE="${REPO_SOURCE:-}"
export REPO_SLUG="${REPO_SLUG:-}"
export TELEMETRY_PLATFORM="pve"
export CACHER="$APT_CACHER"
export CACHER_IP="$APT_CACHER_IP"
if [[ -n "${HTTP_PROXY:-}" ]]; then
@@ -4895,6 +4900,16 @@ EOF
# Point INSTALL_LOG to combined log so get_full_log() finds it
INSTALL_LOG="$combined_log"
fi
# Pull the structured error capture (.errinfo) from the container.
# It contains EXACTLY the output of the command that failed (written by
# silent()/error_handler inside the container) and is the primary source
# for the telemetry error trace - instead of a generic log tail.
local host_errinfo="/tmp/.errinfo-${SESSION_ID}"
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log.errinfo" "$host_errinfo" 2>/dev/null && [[ -s "$host_errinfo" ]]; then
TELEMETRY_ERRINFO="$host_errinfo"
export TELEMETRY_ERRINFO
fi
fi
# Defense-in-depth: Ensure error handling stays disabled during recovery.
@@ -5170,6 +5185,8 @@ EOF
echo -e " Verbose: ${GN}enabled${CL}"
echo ""
msg_info "Restarting installation..."
# New telemetry execution for the retry (previous one keeps its "failed")
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
# Re-run build_container
build_container
return $?
@@ -5209,6 +5226,10 @@ EOF
echo ""
msg_info "Re-running installation script..."
# New telemetry execution for the in-place retry
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
declare -f post_to_api &>/dev/null && post_to_api 2>/dev/null || true
# Re-run install script in existing container (don't destroy/recreate)
set +Eeuo pipefail
trap - ERR
@@ -5272,6 +5293,7 @@ EOF
echo -e " Verbose: ${GN}enabled${CL}"
echo ""
msg_info "Restarting installation..."
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
build_container
return $?
fi
@@ -5301,6 +5323,7 @@ EOF
echo -e " Verbose: ${GN}enabled${CL}"
echo ""
msg_info "Restarting installation..."
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
build_container
return $?
fi
@@ -5325,6 +5348,7 @@ EOF
echo -e " Verbose: ${GN}enabled${CL}"
echo ""
msg_info "Restarting installation..."
declare -f telemetry_new_attempt &>/dev/null && telemetry_new_attempt
build_container
return $?
fi
@@ -6999,6 +7023,16 @@ ensure_log_on_host() {
rm -f "$temp_log"
fi
fi
# Also pull the structured error capture (.errinfo) so the telemetry error
# trace shows the failing command's exact output (signal-exit paths reach
# this via on_exit before/instead of the recovery flow)
if [[ -z "${TELEMETRY_ERRINFO:-}" || ! -s "${TELEMETRY_ERRINFO:-}" ]]; then
local host_errinfo="/tmp/.errinfo-${SESSION_ID}"
if timeout 8 pct pull "$CTID" "/root/.install-${SESSION_ID}.log.errinfo" "$host_errinfo" 2>/dev/null && [[ -s "$host_errinfo" ]]; then
TELEMETRY_ERRINFO="$host_errinfo"
export TELEMETRY_ERRINFO
fi
fi
if [[ -s "$combined_log" ]]; then
INSTALL_LOG="$combined_log"
fi