Files
Enclume/docker/catalog-sync.sh
T
hcornet c85aaaadf4
build / Garde-fou (pull_request) Successful in 11s
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (pull_request) Skipped
build / Images Harbor (web, Dockerfile) (pull_request) Skipped
build / Images Harbor (catalog-sync, Dockerfile.catalog-sync) (push) Successful in 9m45s
build / Garde-fou (push) Successful in 10s
build / Images Harbor (web, Dockerfile) (push) Successful in 11m28s
Reprise du rechargement, version sans prefixe v
2026-09-10 14:28:36 +02:00

87 lines
3.1 KiB
Bash

#!/bin/sh
# Clone ou met a jour le depot du catalogue, publie son contenu dans le volume
# partage, puis notifie l'application. Boucle jusqu'a l'arret du conteneur.
#
# La publication passe par un lien symbolique : on ne peut pas renommer le
# point de montage lui-meme, mais on peut faire basculer un lien a l'interieur,
# et cette bascule est atomique. L'application lit CATALOG_DEST/actuel.
set -eu
: "${CATALOG_DEST:=/catalogue}"
: "${CATALOG_BRANCH:=main}"
: "${CATALOG_SUBDIR:=catalog}"
: "${SYNC_INTERVAL:=300}"
: "${REVISIONS_CONSERVEES:=3}"
if [ -z "${CATALOG_REPO:-}" ]; then
echo "catalog-sync : CATALOG_REPO non defini. L'application utilisera le catalogue de son image."
# On reste en vie sans rien faire : le conteneur ne doit pas boucler en redemarrage.
while true; do sleep 3600; done
fi
TRAVAIL=/tmp/depot
TEMOIN=/tmp/derniere-revision-confirmee
# Previent l'application, et retient si elle a repondu. Tant que la reponse
# n'est pas obtenue, on retente au cycle suivant : au demarrage, catalog-sync
# publie souvent avant que web n'ecoute, et sans cette reprise le site
# resterait sur le catalogue charge a son lancement.
prevenir_application() {
revision="$1"
[ -n "${RELOAD_URL:-}" ] || return 0
[ "$(cat "$TEMOIN" 2>/dev/null)" = "$revision" ] && return 0
if curl -fsS --max-time 10 -X POST "$RELOAD_URL" >/dev/null 2>&1; then
echo "$revision" > "$TEMOIN"
echo "catalog-sync : application rechargee ($revision)"
else
echo "catalog-sync : application injoignable, nouvelle tentative au prochain cycle" >&2
fi
}
sync_une_fois() {
if [ -d "$TRAVAIL/.git" ]; then
git -C "$TRAVAIL" fetch --quiet --depth 1 origin "$CATALOG_BRANCH" || return 1
git -C "$TRAVAIL" reset --quiet --hard "origin/$CATALOG_BRANCH" || return 1
else
rm -rf "$TRAVAIL"
git clone --quiet --depth 1 --branch "$CATALOG_BRANCH" "$CATALOG_REPO" "$TRAVAIL" || return 1
fi
SOURCE="$TRAVAIL/$CATALOG_SUBDIR"
if [ ! -d "$SOURCE" ]; then
echo "catalog-sync : le repertoire $CATALOG_SUBDIR est absent du depot." >&2
return 1
fi
REVISION=$(git -C "$TRAVAIL" rev-parse --short HEAD) || return 1
CIBLE="$CATALOG_DEST/rev-$REVISION"
if [ -L "$CATALOG_DEST/actuel" ] && [ "$(readlink "$CATALOG_DEST/actuel")" = "$CIBLE" ]; then
prevenir_application "$REVISION" # publie, mais l'application l'ignore peut-etre encore
return 0
fi
rm -rf "$CIBLE.partiel" "$CIBLE"
mkdir -p "$CIBLE.partiel"
cp -a "$SOURCE"/. "$CIBLE.partiel"/ || return 1
mv "$CIBLE.partiel" "$CIBLE" || return 1
# Bascule atomique du lien, puis menage des anciennes revisions.
ln -sfn "$CIBLE" "$CATALOG_DEST/actuel.neuf"
mv -f "$CATALOG_DEST/actuel.neuf" "$CATALOG_DEST/actuel" || return 1
ls -1dt "$CATALOG_DEST"/rev-* 2>/dev/null | tail -n +$((REVISIONS_CONSERVEES + 1)) | while read -r vieux; do
rm -rf "$vieux"
done
echo "catalog-sync : catalogue publie ($REVISION)"
prevenir_application "$REVISION"
}
while true; do
if ! sync_une_fois; then
echo "catalog-sync : echec de la synchronisation, nouvelle tentative dans ${SYNC_INTERVAL}s" >&2
fi
sleep "$SYNC_INTERVAL"
done