From 168b3a411f41aff4725971504f54e8070d3bdf0f Mon Sep 17 00:00:00 2001 From: MickLesk <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:17:28 +0200 Subject: [PATCH 1/2] fix: implement exponential backoff for curl retries in _cs_curl_retry function --- lxc/install.func | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/lxc/install.func b/lxc/install.func index de7979f..b12bf4d 100644 --- a/lxc/install.func +++ b/lxc/install.func @@ -54,14 +54,35 @@ _CS_CURL_RETRY=(--retry 3 --retry-delay 1 --retry-connrefused --connect-timeout # curl -S prints one line per failed attempt, so a download that recovers on the # second try would show the user two errors and then quietly work — during a # spinner, no less. Hold stderr back and release it only if every attempt failed. +# +# A container is at its most fragile right after boot (DNS/routing still +# settling), so this retries with growing backoff and a growing per-attempt +# timeout instead of curl's own flat `--retry-delay`, matching the pattern +# already used by curl_with_retry() in lib/system.func. _cs_curl_retry() { local url="${1:?url}" err rc=0 + local attempt=1 max_attempts=4 backoff=1 timeout=30 + err="$(mktemp 2>/dev/null)" || { - curl -fsSL "${_CS_CURL_RETRY[@]}" "$url" + curl -fsSL --connect-timeout 10 --max-time "$timeout" "$url" return } - curl -fsSL "${_CS_CURL_RETRY[@]}" "$url" 2>"$err" || rc=$? - ((rc != 0)) && cat "$err" >&2 + + while [[ $attempt -le $max_attempts ]]; do + if curl -fsSL --connect-timeout 10 --max-time "$timeout" "$url" 2>"$err"; then + rm -f "$err" + return 0 + fi + rc=$? + ((attempt == max_attempts)) && break + sleep "$backoff" + backoff=$((backoff * 2)) + ((backoff > 30)) && backoff=30 + timeout=$((timeout * 2)) + ((attempt++)) + done + + cat "$err" >&2 rm -f "$err" return "$rc" } From f2997b9c87c70ef035af504f28eb3bd55eba9391 Mon Sep 17 00:00:00 2001 From: "CanbiZ (MickLesk)" <47820557+MickLesk@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:18:28 +0200 Subject: [PATCH 2/2] Clean up comments in lxc/install.func Removed comments explaining retry options and behavior for curl in the install function. --- lxc/install.func | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/lxc/install.func b/lxc/install.func index b12bf4d..8e6443d 100644 --- a/lxc/install.func +++ b/lxc/install.func @@ -45,20 +45,10 @@ _cs_core_url() { echo "${COMMUNITY_SCRIPTS_CORE_URL:-https://raw.githubusercontent.com/community-scripts/core/main}/${1:?func path}" } -# Retry options for engine fetches. Repeated here rather than taken from -# core/build.func, which stays on the host while this file is piped into the -# container and has to stand alone. A container is at its most fragile right -# after boot, before DNS is up; core/build.func carries the full reasoning. _CS_CURL_RETRY=(--retry 3 --retry-delay 1 --retry-connrefused --connect-timeout 10) # curl -S prints one line per failed attempt, so a download that recovers on the -# second try would show the user two errors and then quietly work — during a -# spinner, no less. Hold stderr back and release it only if every attempt failed. -# -# A container is at its most fragile right after boot (DNS/routing still -# settling), so this retries with growing backoff and a growing per-attempt -# timeout instead of curl's own flat `--retry-delay`, matching the pattern -# already used by curl_with_retry() in lib/system.func. + _cs_curl_retry() { local url="${1:?url}" err rc=0 local attempt=1 max_attempts=4 backoff=1 timeout=30