docker/sync/sync.sh hinzugefügt
This commit is contained in:
@@ -0,0 +1,198 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
REPO_PATH="/srv/flatpak-mirror/repo"
|
||||||
|
CONFIG_SRC="/config/apps.yaml"
|
||||||
|
GIT_CACHE="/tmp/config-repo"
|
||||||
|
ARCH="x86_64"
|
||||||
|
|
||||||
|
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"; }
|
||||||
|
|
||||||
|
# --- 1. apps.yaml besorgen -------------------------------------------------
|
||||||
|
|
||||||
|
# Setzt HTTP-Basic-Auth fuer git ueber GIT_CONFIG_*-Umgebungsvariablen
|
||||||
|
# (git >= 2.31). Vorteil gegenueber "https://user:token@host/...": das Token
|
||||||
|
# steht weder in der URL (die in Logs auftauchen koennte) noch als
|
||||||
|
# Kommandozeilenargument (das per "ps aux" auf dem Host sichtbar waere).
|
||||||
|
configure_git_auth() {
|
||||||
|
unset GIT_CONFIG_COUNT GIT_CONFIG_KEY_0 GIT_CONFIG_VALUE_0
|
||||||
|
if [ -n "${GIT_USERNAME:-}" ] && [ -n "${GIT_TOKEN:-}" ]; then
|
||||||
|
log "Git: verwende Token-Authentifizierung (Benutzer: ${GIT_USERNAME})"
|
||||||
|
export GIT_CONFIG_COUNT=1
|
||||||
|
export GIT_CONFIG_KEY_0="http.extraHeader"
|
||||||
|
export GIT_CONFIG_VALUE_0="Authorization: Basic $(printf '%s' "${GIT_USERNAME}:${GIT_TOKEN}" | base64 | tr -d '\n')"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
get_config() {
|
||||||
|
if [ -n "${GIT_REPO_URL:-}" ]; then
|
||||||
|
configure_git_auth
|
||||||
|
|
||||||
|
if [ -d "$GIT_CACHE/.git" ]; then
|
||||||
|
log "Git: hole Updates aus ${GIT_REPO_URL}"
|
||||||
|
git -C "$GIT_CACHE" fetch --quiet origin "$GIT_BRANCH"
|
||||||
|
git -C "$GIT_CACHE" reset --hard --quiet "origin/${GIT_BRANCH}"
|
||||||
|
else
|
||||||
|
log "Git: klone ${GIT_REPO_URL}"
|
||||||
|
git clone --quiet --branch "$GIT_BRANCH" "$GIT_REPO_URL" "$GIT_CACHE"
|
||||||
|
fi
|
||||||
|
CONFIG_FILE="$GIT_CACHE/apps.yaml"
|
||||||
|
else
|
||||||
|
log "Kein GIT_REPO_URL gesetzt, nutze lokal gemountete ${CONFIG_SRC}"
|
||||||
|
CONFIG_FILE="$CONFIG_SRC"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$CONFIG_FILE" ]; then
|
||||||
|
log "FEHLER: apps.yaml nicht gefunden unter ${CONFIG_FILE}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 2. Repo initialisieren, falls noch nicht vorhanden --------------------
|
||||||
|
init_repo() {
|
||||||
|
mkdir -p "$REPO_PATH"
|
||||||
|
if [ ! -f "$REPO_PATH/config" ]; then
|
||||||
|
log "Initialisiere neues OSTree-Repo unter ${REPO_PATH}"
|
||||||
|
ostree --repo="$REPO_PATH" init --mode=archive-z2
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! ostree --repo="$REPO_PATH" remote list | grep -q '^flathub$'; then
|
||||||
|
log "Richte Flathub als Remote ein"
|
||||||
|
curl -sSL -o /tmp/flathub.gpg "$FLATHUB_GPG_URL"
|
||||||
|
ostree --repo="$REPO_PATH" remote add flathub "$FLATHUB_REMOTE_URL" \
|
||||||
|
--gpg-import=/tmp/flathub.gpg
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 3. Explizit gewuenschte App-Refs aus apps.yaml ------------------------
|
||||||
|
explicit_app_refs() {
|
||||||
|
yq -r '.apps[] | "app/" + .id + "/'"$ARCH"'/" + .branch' "$CONFIG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Hilfsfunktion: Runtime-Abhaengigkeit eines bereits gepullten Refs -----
|
||||||
|
# --- aus der eingebetteten "metadata"-Datei auslesen (Zeile runtime=...) ---
|
||||||
|
get_runtime_dependency() {
|
||||||
|
local ref="$1"
|
||||||
|
local meta dep
|
||||||
|
meta="$(ostree --repo="$REPO_PATH" cat "$ref" /metadata 2>/dev/null || true)"
|
||||||
|
[ -z "$meta" ] && return 0
|
||||||
|
dep="$(echo "$meta" | grep -E '^runtime=' | head -n1 | cut -d= -f2-)"
|
||||||
|
[ -z "$dep" ] && return 0
|
||||||
|
echo "runtime/${dep}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Hilfsfunktion: Commit-Checksum eines Refs finden, egal ob unter -------
|
||||||
|
# --- refs/heads/ oder (Collection-ID-gebunden) refs/mirrors/<id>/ ----------
|
||||||
|
resolve_pulled_checksum() {
|
||||||
|
local ref="$1"
|
||||||
|
if [ -f "$REPO_PATH/refs/heads/$ref" ]; then
|
||||||
|
cat "$REPO_PATH/refs/heads/$ref"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
find "$REPO_PATH/refs/mirrors" -type f -path "*/$ref" 2>/dev/null | head -n1 | xargs -r cat
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 4. Aktuell lokal verwaltete Refs ermitteln (Apps + Runtimes) ----------
|
||||||
|
current_refs() {
|
||||||
|
ostree --repo="$REPO_PATH" refs | grep -E "^(app|runtime)/" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 5. Pull + rekursive Abhaengigkeitsaufloesung --------------------------
|
||||||
|
# Pullt einen einzelnen Ref und legt den passenden heads/-Ref an
|
||||||
|
# (siehe Kommentar bei resolve_pulled_checksum weiter oben).
|
||||||
|
pull_one_ref() {
|
||||||
|
local ref="$1"
|
||||||
|
log "Pull: ${ref}"
|
||||||
|
ostree --repo="$REPO_PATH" pull --mirror flathub "$ref"
|
||||||
|
|
||||||
|
local checksum
|
||||||
|
checksum="$(resolve_pulled_checksum "$ref")"
|
||||||
|
if [ -z "$checksum" ]; then
|
||||||
|
log "FEHLER: Konnte Commit-Checksum fuer ${ref} nach dem Pull nicht ermitteln"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ostree --repo="$REPO_PATH" refs --create="$ref" "$checksum" --force
|
||||||
|
}
|
||||||
|
|
||||||
|
# Nimmt die explizit freigegebenen App-Refs, pullt sie, liest jeweils die
|
||||||
|
# Runtime-Abhaengigkeit aus und haengt sie hinten an die Warteschlange an -
|
||||||
|
# so werden auch mehrstufige Abhaengigkeiten (App -> Runtime -> Basis-Runtime)
|
||||||
|
# vollstaendig aufgeloest. Gibt am Ende alle tatsaechlich benoetigten Refs aus
|
||||||
|
# (Apps + alle aufgeloesten Runtimes), damit sync_refs() weiss, was behalten
|
||||||
|
# werden soll.
|
||||||
|
resolve_and_pull_all() {
|
||||||
|
local -A seen=()
|
||||||
|
local queue=()
|
||||||
|
local ref dep
|
||||||
|
|
||||||
|
while IFS= read -r ref; do
|
||||||
|
[ -z "$ref" ] && continue
|
||||||
|
queue+=("$ref")
|
||||||
|
done < <(explicit_app_refs)
|
||||||
|
|
||||||
|
while [ "${#queue[@]}" -gt 0 ]; do
|
||||||
|
ref="${queue[0]}"
|
||||||
|
queue=("${queue[@]:1}")
|
||||||
|
|
||||||
|
[ -n "${seen[$ref]:-}" ] && continue
|
||||||
|
seen["$ref"]=1
|
||||||
|
|
||||||
|
pull_one_ref "$ref"
|
||||||
|
|
||||||
|
dep="$(get_runtime_dependency "$ref")"
|
||||||
|
if [ -n "$dep" ] && [ -z "${seen[$dep]:-}" ]; then
|
||||||
|
log " -> benoetigt zusaetzlich: ${dep}"
|
||||||
|
queue+=("$dep")
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '%s\n' "${!seen[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 6. Abgleich: pullen was fehlt (inkl. Abhaengigkeiten), loeschen was ---
|
||||||
|
# --- nicht mehr gewuenscht ist ----------------------------------------------
|
||||||
|
sync_refs() {
|
||||||
|
local wanted current
|
||||||
|
|
||||||
|
log "Loese App-Refs und Abhaengigkeiten auf..."
|
||||||
|
wanted="$(resolve_and_pull_all)"
|
||||||
|
current="$(current_refs)"
|
||||||
|
|
||||||
|
log "Verwaltete Refs (Apps + Runtimes):"
|
||||||
|
echo "$wanted" | sed 's/^/ + /'
|
||||||
|
|
||||||
|
# Refs entfernen, die weder explizit freigegeben noch als Abhaengigkeit
|
||||||
|
# noch benoetigt werden
|
||||||
|
while IFS= read -r ref; do
|
||||||
|
[ -z "$ref" ] && continue
|
||||||
|
if ! grep -qxF "$ref" <<< "$wanted"; then
|
||||||
|
log "Entferne nicht mehr benoetigten Ref: ${ref}"
|
||||||
|
ostree --repo="$REPO_PATH" refs --delete "$ref"
|
||||||
|
fi
|
||||||
|
done <<< "$current"
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- 7. Summary aktualisieren -----------------------------------------------
|
||||||
|
update_summary() {
|
||||||
|
log "Aktualisiere Repo-Summary und Static Deltas"
|
||||||
|
flatpak build-update-repo --generate-static-deltas "$REPO_PATH"
|
||||||
|
}
|
||||||
|
|
||||||
|
run_once() {
|
||||||
|
get_config
|
||||||
|
init_repo
|
||||||
|
sync_refs
|
||||||
|
update_summary
|
||||||
|
log "Sync abgeschlossen."
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Hauptschleife ----------------------------------------------------------
|
||||||
|
log "Starte Sync-Loop (Intervall: ${SYNC_INTERVAL_SECONDS}s)"
|
||||||
|
while true; do
|
||||||
|
if run_once; then
|
||||||
|
log "Naechster Lauf in ${SYNC_INTERVAL_SECONDS}s"
|
||||||
|
else
|
||||||
|
log "Sync-Lauf fehlgeschlagen, versuche es beim naechsten Intervall erneut"
|
||||||
|
fi
|
||||||
|
sleep "$SYNC_INTERVAL_SECONDS"
|
||||||
|
done
|
||||||
Reference in New Issue
Block a user