#!/bin/bash # Synct die Paket-Whitelist aus Git und lädt die selektierten Pakete # (inkl. Abhängigkeiten) aus den jeweils angegebenen Fremd-Repos. set -euo pipefail CONFIG_DIR=/etc/mirror CONFIG_REPO_URL="${CONFIG_REPO_URL:?CONFIG_REPO_URL ist nicht gesetzt}" CONFIG_REPO_BRANCH="${CONFIG_REPO_BRANCH:-main}" PACKAGES_FILE="$CONFIG_DIR/packages.yaml" DEST=/data/repo/rpms TMP_REPO_DIR=/etc/yum.repos.d LOCKFILE=/tmp/sync.lock exec 200>"$LOCKFILE" if ! flock -n 200; then echo "[sync] Ein anderer Sync-Lauf ist bereits aktiv, breche ab." exit 0 fi echo "[sync] $(date -Iseconds) Starte Sync-Lauf" # --- 1. Whitelist aus Git holen --------------------------------------- mkdir -p "$CONFIG_DIR" if [ -n "${GIT_SSH_KEY_PATH:-}" ] && [ -f "${GIT_SSH_KEY_PATH:-}" ]; then export GIT_SSH_COMMAND="ssh -i ${GIT_SSH_KEY_PATH} -o StrictHostKeyChecking=accept-new" fi if [ -d "$CONFIG_DIR/.git" ]; then git -C "$CONFIG_DIR" fetch --depth=1 origin "$CONFIG_REPO_BRANCH" git -C "$CONFIG_DIR" reset --hard "origin/$CONFIG_REPO_BRANCH" else git clone --depth=1 --branch "$CONFIG_REPO_BRANCH" "$CONFIG_REPO_URL" "$CONFIG_DIR" fi if [ ! -f "$PACKAGES_FILE" ]; then echo "[sync] FEHLER: $PACKAGES_FILE nicht gefunden." exit 1 fi mkdir -p "$DEST" # --- 2. Pro Quelle: temporäres Repo aktivieren, Pakete gezielt ziehen -- source_count=$(yq -o=json '.sources | length' "$PACKAGES_FILE") for i in $(seq 0 $((source_count - 1))); do src=$(yq -o=json ".sources[$i]" "$PACKAGES_FILE") name=$(echo "$src" | jq -r '.name') baseurl=$(echo "$src" | jq -r '.baseurl') gpgkey=$(echo "$src" | jq -r '.gpgkey // empty') mapfile -t packages < <(echo "$src" | jq -r '.packages[]') if [ "${#packages[@]}" -eq 0 ]; then echo "[sync] Quelle '$name': keine Pakete gelistet, überspringe." continue fi echo "[sync] Quelle '$name': ${#packages[@]} Paket(e) -> $baseurl" repofile="$TMP_REPO_DIR/tmp-${name}.repo" { echo "[tmp-${name}]" echo "name=${name}" echo "baseurl=${baseurl}" echo "enabled=1" if [ -n "$gpgkey" ]; then echo "gpgcheck=1" echo "gpgkey=${gpgkey}" else echo "gpgcheck=0" fi } > "$repofile" # Bei Fehlschlag (z.B. Paket nicht gefunden) diese Quelle nicht den # gesamten Lauf abbrechen lassen, aber laut melden. if ! dnf download --resolve --alldeps \ --disablerepo='*' --enablerepo="tmp-${name}" \ --destdir="$DEST" "${packages[@]}"; then echo "[sync] WARNUNG: Download für Quelle '$name' teilweise fehlgeschlagen." fi rm -f "$repofile" done # --- 3. Alte Paketversionen aufräumen ----------------------------------- echo "[sync] Räume veraltete Paketversionen auf" dnf repomanage --old "$DEST" 2>/dev/null | xargs -r rm -f # --- 4. Pakete mit dem Firmen-Key umsignieren --------------------------- if [ -n "${GPG_KEY_ID:-}" ]; then echo "[sync] Signiere Pakete mit Firmen-Key ${GPG_KEY_ID}" find "$DEST" -name '*.rpm' -print0 \ | xargs -0 -r rpmsign --key-id="$GPG_KEY_ID" --resign else echo "[sync] WARNUNG: GPG_KEY_ID nicht gesetzt, Pakete bleiben unsigniert." fi # --- 5. Repo-Metadaten neu erzeugen ------------------------------------- echo "[sync] Aktualisiere Repo-Metadaten" createrepo_c --update "$DEST" # Optional: Repo-Metadaten (repomd.xml) selbst signieren, für zusätzliche # Integritätsprüfung mit repo_gpgcheck=1 auf Client-Seite if [ -n "${GPG_KEY_ID:-}" ]; then gpg --batch --yes --detach-sign --armor \ -u "$GPG_KEY_ID" -o "$DEST/repodata/repomd.xml.asc" \ "$DEST/repodata/repomd.xml" fi echo "[sync] $(date -Iseconds) Sync-Lauf abgeschlossen"