From 445a8de2b5c2477daa4b760fc304f28170be5091 Mon Sep 17 00:00:00 2001 From: "David M. Klein" <4+leander19961@noreply.localhost> Date: Wed, 2 Sep 2026 14:51:51 +0200 Subject: [PATCH] =?UTF-8?q?Verzeichnis=20'mirror=20'=20l=C3=B6schen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mirror/Dockerfile | 44 --- .../almalinux-baseline.repo | 44 --- mirror/entrypoint.sh | 12 - mirror/run-as-mirror.sh | 62 ----- mirror/sync.sh | 262 ------------------ 5 files changed, 424 deletions(-) delete mode 100644 mirror/Dockerfile delete mode 100644 mirror/config/alma-baseline.repo.d/almalinux-baseline.repo delete mode 100644 mirror/entrypoint.sh delete mode 100644 mirror/run-as-mirror.sh delete mode 100644 mirror/sync.sh diff --git a/mirror/Dockerfile b/mirror/Dockerfile deleted file mode 100644 index a7895cc..0000000 --- a/mirror/Dockerfile +++ /dev/null @@ -1,44 +0,0 @@ -FROM almalinux:9 - -# dnf-plugins-core -> dnf download, repoquery, config-manager -# createrepo_c -> Repo-Metadaten bauen -# rpm-sign, gnupg2 -> Pakete umsignieren -# appstream-glib -> appstream-builder, erzeugt AppStream-Metadaten fuer Discover -# (kommt aus EPEL, daher epel-release zuerst) -# git, openssh-clients -> packages.yaml vor jedem Sync aus einem Git-Repo ziehen -# python3-pyyaml, jq -> packages.yaml (YAML) nach JSON wandeln und auswerten -# util-linux-core -> stellt setpriv (root -> mirror-User droppen) sicher -RUN dnf -y install epel-release \ - && dnf -y install \ - dnf-plugins-core \ - createrepo_c \ - rpm-sign \ - gnupg2 \ - appstream-glib \ - git \ - openssh-clients \ - python3-pyyaml \ - util-linux-core \ - findutils \ - procps-ng \ - jq \ - && dnf clean all - -RUN useradd -r -m -d /var/lib/mirror-gpg mirror - -COPY entrypoint.sh /usr/local/bin/entrypoint.sh -COPY run-as-mirror.sh /usr/local/bin/run-as-mirror.sh -COPY sync.sh /usr/local/bin/sync.sh -RUN chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/run-as-mirror.sh /usr/local/bin/sync.sh - -RUN mkdir -p /srv/dnf /var/cache/mirror /var/lib/mirror-gpg \ - && chown -R mirror:mirror /srv/dnf /var/cache/mirror /var/lib/mirror-gpg - -ENV HOME=/var/lib/mirror-gpg -ENV GNUPGHOME=/var/lib/mirror-gpg/.gnupg - -# Bleibt root: entrypoint.sh chownt den bind-gemounteten ./gpg-Ordner (der dem -# Host gehoert, nicht dem Image) und wechselt danach per setpriv fest zu -# "mirror". Alles Weitere (Sync-Loop, git, dnf download, gpg) laeuft -# unprivilegiert. -ENTRYPOINT ["/usr/local/bin/entrypoint.sh"] diff --git a/mirror/config/alma-baseline.repo.d/almalinux-baseline.repo b/mirror/config/alma-baseline.repo.d/almalinux-baseline.repo deleted file mode 100644 index e9c7c4e..0000000 --- a/mirror/config/alma-baseline.repo.d/almalinux-baseline.repo +++ /dev/null @@ -1,44 +0,0 @@ -# OPTIONAL. Standardmaessig fragt sync.sh fuer die "was kann Alma sowieso -# schon aufloesen?"-Pruefung einfach die im Mirror-Image bereits vorhandenen -# System-Repos ab (das Image ist selbst AlmaLinux, hat also baseos/appstream/ -# extras/crb + epel schon konfiguriert) - dafuer ist diese Datei NICHT noetig. -# -# Setze die Env-Variable ALMA_BASELINE_REPOSDIR=/etc/mirror/alma-baseline.repo.d, -# wenn du stattdessen explizit gegen andere/eigene Repo-Definitionen pruefen -# willst (z.B. anderer Releasever, eigener interner Alma-Spiegel). Es wird -# daraus nie etwas gespiegelt, nur `dnf repoquery` dagegen ausgefuehrt. - -[baseos] -name=AlmaLinux $releasever - BaseOS -mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/baseos -gpgcheck=1 -gpgkey=https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9 -enabled=1 - -[appstream] -name=AlmaLinux $releasever - AppStream -mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/appstream -gpgcheck=1 -gpgkey=https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9 -enabled=1 - -[extras] -name=AlmaLinux $releasever - Extras -mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/extras -gpgcheck=1 -gpgkey=https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9 -enabled=1 - -[crb] -name=AlmaLinux $releasever - CRB -mirrorlist=https://mirrors.almalinux.org/mirrorlist/$releasever/crb -gpgcheck=1 -gpgkey=https://repo.almalinux.org/almalinux/RPM-GPG-KEY-AlmaLinux-9 -enabled=1 - -[epel] -name=Extra Packages for Enterprise Linux $releasever - $basearch -metalink=https://mirrors.fedoraproject.org/metalink?repo=epel-$releasever&arch=$basearch&infra=$infra&content=$contentdir -gpgcheck=1 -gpgkey=https://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-9 -enabled=1 diff --git a/mirror/entrypoint.sh b/mirror/entrypoint.sh deleted file mode 100644 index 5444f7f..0000000 --- a/mirror/entrypoint.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -# Startet als root, damit der bind-gemountete ./gpg-Ordner (der auf dem Host -# meist root oder dem einladenden User gehoert) dem "mirror"-User im Container -# gehoert - danach wird per setpriv dauerhaft zu diesem unprivilegierten User -# gewechselt (ersetzt den Prozess direkt, kein Wrapper-Kindprozess, damit -# Signale/PID 1 sauber bleiben). -set -euo pipefail - -mkdir -p /var/lib/mirror-gpg /srv/dnf /var/cache/mirror -chown -R mirror:mirror /var/lib/mirror-gpg /srv/dnf /var/cache/mirror - -exec setpriv --reuid=mirror --regid=mirror --init-groups /usr/local/bin/run-as-mirror.sh diff --git a/mirror/run-as-mirror.sh b/mirror/run-as-mirror.sh deleted file mode 100644 index fdc9469..0000000 --- a/mirror/run-as-mirror.sh +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/bash -# Laeuft als unprivilegierter User "mirror" (siehe entrypoint.sh, der als -# root die Verzeichnisrechte setzt und dann per setpriv hierher wechselt). -set -euo pipefail - -: "${GPG_NAME:?GPG_NAME muss gesetzt sein}" -: "${GPG_EMAIL:?GPG_EMAIL muss gesetzt sein}" -: "${SYNC_INTERVAL_SECONDS:=21600}" - -mkdir -p "$GNUPGHOME" -chmod 700 "$GNUPGHOME" -echo "allow-loopback-pinentry" > "$GNUPGHOME/gpg-agent.conf" -echo "pinentry-mode loopback" > "$GNUPGHOME/gpg.conf" - -PASSPHRASE_FILE=/run/secrets/gpg_passphrase -if [ -z "${GPG_PASSPHRASE:-}" ] && [ ! -f "$PASSPHRASE_FILE" ]; then - PASSPHRASE_FILE="" -fi - -# GPG-Key nur beim allerersten Start erzeugen. Das gnupg-Home liegt im -# bind-gemounteten ./gpg-Ordner neben der docker-compose.yml - der Key (und -# damit der Public Key, den alle Clients einmalig vertrauen) bleibt ueber -# Container-Neustarts/-Updates hinweg gleich UND ist direkt auf dem Host -# sichtbar/sicherbar, statt in einem anonymen Docker-Volume zu stecken. -if ! gpg --batch --list-secret-keys "$GPG_NAME" >/dev/null 2>&1; then - echo "[entrypoint] Erzeuge neuen Signing-Key fuer '$GPG_NAME <$GPG_EMAIL>' ..." - KEYPARAMS=$(mktemp) - { - echo "%echo Generating mirror signing key" - echo "Key-Type: RSA" - echo "Key-Length: 4096" - echo "Name-Real: $GPG_NAME" - echo "Name-Email: $GPG_EMAIL" - echo "Expire-Date: 0" - if [ -n "$PASSPHRASE_FILE" ]; then - echo "Passphrase: $(cat "$PASSPHRASE_FILE")" - else - echo "%no-protection" - fi - echo "%commit" - } > "$KEYPARAMS" - gpg --batch --gen-key "$KEYPARAMS" - rm -f "$KEYPARAMS" -else - echo "[entrypoint] Signing-Key existiert bereits, wird wiederverwendet." -fi - -mkdir -p /srv/dnf -gpg --batch --yes --armor --export "$GPG_NAME" > /srv/dnf/RPM-GPG-KEY-mirror -echo "[entrypoint] Public Key nach /srv/dnf/RPM-GPG-KEY-mirror exportiert." - -term_handler() { - echo "[entrypoint] Beende nach aktuellem Sync-Lauf ..." - exit 0 -} -trap term_handler SIGTERM SIGINT - -while true; do - /usr/local/bin/sync.sh || echo "[entrypoint] sync.sh ist mit Fehler beendet, naechster Versuch in ${SYNC_INTERVAL_SECONDS}s" - sleep "$SYNC_INTERVAL_SECONDS" & - wait $! -done diff --git a/mirror/sync.sh b/mirror/sync.sh deleted file mode 100644 index e0e67f6..0000000 --- a/mirror/sync.sh +++ /dev/null @@ -1,262 +0,0 @@ -#!/bin/bash -# Ein Sync-Durchlauf: -# 0. packages.yaml frisch aus Git ziehen (Fremdrepos + Paketnamen je Repo) -# 1. je Fremdrepo genau die dort gelisteten Pakete per `dnf download` holen -# 2. Pakete rauswerfen, die AlmaLinux (BaseOS/AppStream/Extras/CRB/EPEL) -# sowieso schon bereitstellt (ausser force_include-Ausnahmen) -# 3. verbleibende Pakete mit dem eigenen Mirror-Key umsignieren -# 4. Repo-Metadaten (createrepo_c) + AppStream-Metadaten (fuer Discover) bauen -# 5. repomd.xml signieren, Client-.repo-Datei schreiben -set -uo pipefail - -CACHE=/var/cache/mirror -OUT=/srv/dnf -SOURCES_GIT_CHECKOUT="$CACHE/sources-git" -PACKAGES_JSON="$CACHE/packages.json" - -: "${GPG_NAME:?}" -: "${MIRROR_DOMAIN:?}" -: "${SOURCES_GIT_URL:?SOURCES_GIT_URL muss auf das Git-Repo mit packages.yaml zeigen}" -: "${SOURCES_GIT_REF:=main}" -: "${ALMA_RELEASEVER:=9}" -: "${ALMA_BASEARCH:=x86_64}" -: "${ALMA_BASELINE_REPOIDS:=baseos,appstream,extras,crb,epel}" - -mkdir -p "$CACHE/stage" "$CACHE/appstream-cache" "$CACHE/tmp-repos" "$OUT" - -log() { echo "[sync $(date '+%F %T')] $*"; } - -# Zieht packages.yaml vor JEDEM Sync-Lauf frisch aus einem Git-Repo (statt aus -# lokal gemounteten Dateien), damit Aenderungen an der Paketliste ohne -# Container-Neubau/-Neustart wirksam werden. -fetch_packages_yaml() { - if [ -n "${SOURCES_GIT_SSH_KEY:-}" ] && [ -f "$SOURCES_GIT_SSH_KEY" ]; then - export GIT_SSH_COMMAND="ssh -i ${SOURCES_GIT_SSH_KEY} -o IdentitiesOnly=yes -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${CACHE}/known_hosts" - fi - - if [ -d "$SOURCES_GIT_CHECKOUT/.git" ]; then - log "Aktualisiere packages.yaml aus Git ($SOURCES_GIT_URL @ $SOURCES_GIT_REF) ..." - if git -C "$SOURCES_GIT_CHECKOUT" fetch --depth 1 origin "$SOURCES_GIT_REF" >>"$CACHE/git-sources.log" 2>&1 \ - && git -C "$SOURCES_GIT_CHECKOUT" reset --hard FETCH_HEAD >>"$CACHE/git-sources.log" 2>&1 \ - && git -C "$SOURCES_GIT_CHECKOUT" clean -fdx >>"$CACHE/git-sources.log" 2>&1; then - : - else - log "WARNUNG: git fetch fehlgeschlagen, siehe $CACHE/git-sources.log - verwende letzten bekannten Stand von packages.yaml weiter." - fi - else - log "Klone packages.yaml aus Git ($SOURCES_GIT_URL @ $SOURCES_GIT_REF) ..." - rm -rf "$SOURCES_GIT_CHECKOUT" - if ! git clone --branch "$SOURCES_GIT_REF" --single-branch --depth 1 \ - "$SOURCES_GIT_URL" "$SOURCES_GIT_CHECKOUT" >>"$CACHE/git-sources.log" 2>&1; then - log "FEHLER: Erstklon von packages.yaml aus Git fehlgeschlagen, siehe $CACHE/git-sources.log" - return 1 - fi - fi - - local yaml_file="$SOURCES_GIT_CHECKOUT/packages.yaml" - if [ ! -f "$yaml_file" ]; then - log "FEHLER: $yaml_file existiert nicht im Git-Repo." - return 1 - fi - - if ! python3 -c ' -import sys, json, yaml -with open(sys.argv[1]) as f: - data = yaml.safe_load(f) or {} -data.setdefault("repos", []) -data.setdefault("force_include", []) -json.dump(data, sys.stdout) -' "$yaml_file" > "$PACKAGES_JSON.tmp" 2>"$CACHE/packages-yaml-parse.log"; then - log "FEHLER: packages.yaml ist kein gueltiges YAML, siehe $CACHE/packages-yaml-parse.log" - rm -f "$PACKAGES_JSON.tmp" - return 1 - fi - mv "$PACKAGES_JSON.tmp" "$PACKAGES_JSON" -} - -refresh_alma_names() { - log "Ermittle Paketnamen, die AlmaLinux selbst bereitstellt ..." - local -a enable_args=() - local id - IFS=',' read -ra ids <<< "$ALMA_BASELINE_REPOIDS" - for id in "${ids[@]}"; do - enable_args+=(--enablerepo="$id") - done - - local -a reposdir_args=() - if [ -n "${ALMA_BASELINE_REPOSDIR:-}" ] && ls "${ALMA_BASELINE_REPOSDIR}"/*.repo >/dev/null 2>&1; then - reposdir_args=(--setopt="reposdir=${ALMA_BASELINE_REPOSDIR}") - fi - - if ! dnf repoquery -y --quiet -a --qf '%{name}' \ - --disablerepo='*' "${enable_args[@]}" \ - --releasever="$ALMA_RELEASEVER" --forcearch="$ALMA_BASEARCH" \ - "${reposdir_args[@]}" 2>>"$CACHE/repoquery.log" | sort -u > "$CACHE/alma-names.txt.tmp"; then - log "WARNUNG: repoquery gegen AlmaLinux-Baseline fehlgeschlagen, siehe $CACHE/repoquery.log" - log "Verwende ggf. vorherigen Stand von alma-names.txt weiter." - rm -f "$CACHE/alma-names.txt.tmp" - return - fi - mv "$CACHE/alma-names.txt.tmp" "$CACHE/alma-names.txt" - log "$(wc -l < "$CACHE/alma-names.txt") Paketnamen als 'ueber Alma aufloesbar' erfasst." -} - -is_force_included() { - local name="$1" f - for f in "${FORCE_INCLUDE_NAMES[@]}"; do - [ "$f" = "$name" ] && return 0 - done - return 1 -} - -# Args: id baseurl gpgkey gpgcheck(0/1) paket1 [paket2 ...] -sync_one_repo() { - local id="$1" baseurl="$2" gpgkey="$3" gpgcheck="$4" - shift 4 - local -a packages=("$@") - local stage="$CACHE/stage/$id" - local out="$OUT/$id" - local tmp_repofile="$CACHE/tmp-repos/$id.repo" - - log "== $id: hole ${#packages[@]} Paket(e) aus $baseurl ==" - rm -rf "$CACHE/tmp-repos"/*.repo - { - echo "[$id]" - echo "name=$id" - echo "baseurl=$baseurl" - echo "enabled=1" - echo "gpgcheck=$gpgcheck" - [ -n "$gpgkey" ] && echo "gpgkey=$gpgkey" - } > "$tmp_repofile" - - rm -rf "$stage" - mkdir -p "$stage" - if ! dnf --setopt="reposdir=$CACHE/tmp-repos" \ - --disablerepo='*' --enablerepo="$id" \ - --forcearch="$ALMA_BASEARCH" \ - download --destdir="$stage" "${packages[@]}" \ - >>"$CACHE/download-$id.log" 2>&1; then - log "FEHLER: dnf download fuer $id fehlgeschlagen, siehe $CACHE/download-$id.log - ueberspringe." - return 1 - fi - - log "== $id: filtere Pakete, die Alma bereits bereitstellt ==" - local removed=0 kept=0 - while IFS= read -r -d '' rpm; do - local name - name=$(rpm -qp --qf '%{NAME}' "$rpm" 2>/dev/null) - if [ -z "$name" ]; then - continue - fi - if grep -qxF "$name" "$CACHE/alma-names.txt" 2>/dev/null && ! is_force_included "$name"; then - rm -f "$rpm" - removed=$((removed + 1)) - else - kept=$((kept + 1)) - fi - done < <(find "$stage" -maxdepth 1 -name '*.rpm' -print0) - log "$id: $kept Pakete werden gespiegelt, $removed uebersprungen (bereits ueber Alma verfuegbar)." - - log "== $id: gleiche mit oeffentlichem Ausgabeverzeichnis ab und signiere neue/geaenderte Pakete ==" - mkdir -p "$out" - local changed_list - changed_list=$(mktemp) - rsync -ai --delete --include='*.rpm' --exclude='*' "$stage"/ "$out"/ \ - | awk '/^[><]f/{print $2}' > "$changed_list" - - local resign_failed=0 - while IFS= read -r f; do - [ -z "$f" ] && continue - if ! rpmsign --resign \ - --define "_gpg_name $GPG_NAME" \ - --define "_gpg_path $GNUPGHOME" \ - "$out/$f" >>"$CACHE/rpmsign-$id.log" 2>&1; then - log "FEHLER: Signieren von $out/$f fehlgeschlagen, siehe $CACHE/rpmsign-$id.log" - resign_failed=1 - fi - done < "$changed_list" - local changed_count - changed_count=$(wc -l < "$changed_list") - rm -f "$changed_list" - log "$id: $changed_count Pakete neu signiert." - if [ "$resign_failed" -ne 0 ]; then - log "FEHLER: mind. ein Paket in $id konnte nicht signiert werden - ueberspringe Metadaten-Neubau fuer $id." - return 1 - fi - - log "== $id: baue Repo-Metadaten ==" - if ! createrepo_c --update "$out" >>"$CACHE/createrepo-$id.log" 2>&1; then - log "FEHLER: createrepo_c fuer $id fehlgeschlagen, siehe $CACHE/createrepo-$id.log" - return 1 - fi - - if command -v appstream-builder >/dev/null 2>&1; then - log "== $id: baue AppStream-Metadaten (fuer Discover/GNOME Software) ==" - local asout="$CACHE/appstream/$id" - mkdir -p "$asout" - if appstream-builder \ - --origin="$id" --basename="$id" \ - --cache-dir="$CACHE/appstream-cache/$id" \ - --packages-dir="$out" \ - --output-dir="$asout" \ - --min-icon-size=48 --enable-hidpi \ - >>"$CACHE/appstream-$id.log" 2>&1; then - [ -f "$asout/$id.xml.gz" ] && modifyrepo_c --mdtype=appstream "$asout/$id.xml.gz" "$out/repodata" - [ -f "$asout/$id-icons.tar.gz" ] && modifyrepo_c --mdtype=appstream-icons "$asout/$id-icons.tar.gz" "$out/repodata" - else - log "WARNUNG: appstream-builder fuer $id fehlgeschlagen (nicht fatal), siehe $CACHE/appstream-$id.log" - fi - else - log "WARNUNG: appstream-builder nicht installiert - $id erscheint ohne App-Katalogeintrag in Discover." - fi - - log "== $id: signiere repomd.xml ==" - gpg --batch --yes --detach-sign --armor --local-user "$GPG_NAME" \ - --output "$out/repodata/repomd.xml.asc" "$out/repodata/repomd.xml" - - cat > "$OUT/$id.repo" <