diff --git a/.docker/cscli-hub-mirror.sh b/.docker/cscli-hub-mirror.sh new file mode 100644 index 000000000..039177aec --- /dev/null +++ b/.docker/cscli-hub-mirror.sh @@ -0,0 +1,377 @@ +# shellcheck shell=sh +# CrowdSec hub mirror retry for cscli. POSIX sh, sourced by .docker/docker-entrypoint.sh and by +# configs/crowdsec/install_hub_items.sh. The image copies it to /usr/local/lib/charon/cscli-hub-mirror.sh. +# +# cscli reads one hub URL template from its config (the hidden key __hub_url_template__). When the hub CDN +# is unreachable, a retry runs cscli with a derived copy of the config whose template points at the raw +# GitHub mirror. The live config is never written. +# +# The rules follow backend/internal/crowdsec/hub_mirror.go (template checks, refusal of a template the +# operator already set, the network-failure markers). Keep the two in step. The timeout classification (_hub_timed_out: +# exit status, signal text, budget expiry) exists only here: the image runs cscli under busybox timeout, which reports +# a trapped TERM as the command's own exit 1, and the Go side does not classify exit statuses. +# +# Internal state, set by this helper and not meant for operators: +# CHARON_CSCLI_MIRROR_CONFIG path of the derived config while it exists +# CHARON_CSCLI_MIRROR_FIRST "1" once a mirror retry answered: later cscli_hub calls go mirror-first + +# The shell always uses the built-in mirror template, with no operator mirror base (the Go side can use one). +_HUB_MIRROR_TEMPLATE='https://raw.githubusercontent.com/crowdsecurity/hub/%s/%s' +_HUB_MIRROR_KEY='__hub_url_template__' +_HUB_MIRROR_PREFIX='.charon-hub-mirror-' + +# Plain foreground fallback for callers without the entrypoint's stop-aware runner (install_hub_items.sh). +if ! command -v run_interruptible >/dev/null 2>&1; then + run_interruptible() { + "$@" + } +fi + +# hub_mirror_template_valid