From 94460a999d7ad18cb42f320719861066a48c765a Mon Sep 17 00:00:00 2001 From: gunnar Date: Sat, 30 May 2026 15:42:14 +0200 Subject: [PATCH] fix: Update-Skript, Containerfile-Optimierungen und chunkah-Rechunking - notify-bootc-user.sh: D-Bus-Umgebung korrekt fuer Systemd-Service, jq-basierter Staging-Check (.status.staged != null), Guard Clauses, -Variable entfernt - Containerfile: COPY --chmod=755 fuer Skript-Permissions - build/20-multimedia.sh: Redundantes dnf5 clean all entfernt - build/30-virt.sh: dnf5 autoremove und Cleanup entfernt - build/40-remove-packages.sh: || true entfernt (Fehler sichtbar machen) - build/50-prepare-flatpak-for-bazaar.sh: curl -f --retry 3 hinzugefuegt - build.yml: chunkah Rechunk-Step fuer content-based Layers (Delta-Updates), Cache-Key erweitert (scripts/**), continue-on-error entfernt - build-installer-iso.yml: concurrency-Block hinzugefuegt --- .github/workflows/build-installer-iso.yml | 4 + .github/workflows/build.yml | 31 +++++- Containerfile | 3 +- build/20-multimedia.sh | 5 +- build/30-virt.sh | 6 +- build/40-remove-packages.sh | 2 +- build/50-prepare-flatpak-for-bazaar.sh | 2 +- scripts/notify-bootc-user.sh | 110 ++++++++++------------ 8 files changed, 89 insertions(+), 74 deletions(-) diff --git a/.github/workflows/build-installer-iso.yml b/.github/workflows/build-installer-iso.yml index ebcb7c8..f832612 100644 --- a/.github/workflows/build-installer-iso.yml +++ b/.github/workflows/build-installer-iso.yml @@ -3,6 +3,10 @@ name: Build Installer ISO on: workflow_dispatch: +concurrency: + group: ${{ github.workflow }}-${{ github.ref || github.run_id }} + cancel-in-progress: true + jobs: build-iso: runs-on: ubuntu-latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb50cb5..b77af5d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -39,7 +39,6 @@ jobs: - name: Mount BTRFS for podman storage id: container-storage-action uses: ublue-os/container-storage-action@911baca08baf30c8654933e9e9723cb399892140 # main - continue-on-error: true with: target-dir: /var/lib/containers mount-opts: compress-force=zstd:2 @@ -75,9 +74,9 @@ jobs: /var/lib/containers/storage/overlay ~/.cache/buildah /tmp/.buildah-cache - key: ${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('Containerfile', 'build/**', 'configs/**') }}-${{ github.ref }} + key: ${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('Containerfile', 'build/**', 'configs/**', 'scripts/**') }}-${{ github.ref }} restore-keys: | - ${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('Containerfile', 'build/**', 'configs/**') }}- + ${{ runner.os }}-${{ github.workflow }}-${{ hashFiles('Containerfile', 'build/**', 'configs/**', 'scripts/**') }}- ${{ runner.os }}-${{ github.workflow }}- - name: Build Image @@ -91,6 +90,32 @@ jobs: labels: ${{ steps.metadata.outputs.labels }} oci: true + - name: Rechunk with chunkah + run: | + set -euo pipefail + + IMG="localhost/${{ env.IMAGE_NAME }}:${{ env.DEFAULT_TAG }}" + CHUNKED_IMG="localhost/${{ env.IMAGE_NAME }}-chunked:${{ env.DEFAULT_TAG }}" + + # Image-Config fuer chunkah sichern (Labels, Annotations, etc.) + CONFIG=$(sudo buildah inspect "$IMG" | jq -c .) + + # chunkah: content-based Layer-Splitting + # --max-layers 128: Desktop-Images brauchen mehr als Default (64) + # --prune /sysroot/: entfernt OSTree-Metadaten (optional seit bootc 1.1.3) + # --label ostree.*: entfernt gueltigkeitsfaehige ostree-Labels + sudo buildah build --skip-unused-stages=false \ + --from "$IMG" \ + --build-arg CHUNKAH_CONFIG_STR="$CONFIG" \ + --build-arg "CHUNKAH_ARGS=--prune /sysroot/ --max-layers 128 --label ostree.commit- --label ostree.final-diffid-" \ + -t "$CHUNKED_IMG" \ + https://github.com/coreos/chunkah/releases/download/v0.5.0/Containerfile.splitter + + # Platz freigeben: Original und Zwischenprodukt entfernen + sudo buildah rmi "$IMG" + sudo buildah tag "$CHUNKED_IMG" "$IMG" + sudo buildah rmi "$CHUNKED_IMG" + - name: Login to GitHub Container Registry uses: docker/login-action@650006c6eb7dba73a995cc03b0b2d7f5ca915bee # v3 if: github.event_name != 'pull_request' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) diff --git a/Containerfile b/Containerfile index efa0df7..fd5592c 100644 --- a/Containerfile +++ b/Containerfile @@ -82,8 +82,7 @@ COPY configs/bootc-timer-override.conf /etc/systemd/system/bootc-fetch-apply-upd COPY configs/bootc-override.conf /etc/systemd/system/bootc-fetch-apply-updates.service.d/override.conf # 3. Kopiere das Benachrichtigungs-Skript -# Wichtig: Das Skript muss auf deinem Host bereits mit 'chmod +x' markiert sein! -COPY scripts/notify-bootc-user.sh /usr/bin/ +COPY --chmod=755 scripts/notify-bootc-user.sh /usr/bin/ # ============================================================================= # SYSTEMD SERVICES & PRESETS (Modern Bootc Architecture) diff --git a/build/20-multimedia.sh b/build/20-multimedia.sh index 3ed59b6..96c6164 100755 --- a/build/20-multimedia.sh +++ b/build/20-multimedia.sh @@ -31,7 +31,4 @@ dnf5 install -y @multimedia # rocm-runtime -# --- 2. Die sofortige Bereinigung (WICHTIG!) --- -echo "Cleaning up this layer..." -dnf5 clean all || true -rm -rf /tmp/* /var/tmp/* || true + diff --git a/build/30-virt.sh b/build/30-virt.sh index 1a81e79..b313817 100755 --- a/build/30-virt.sh +++ b/build/30-virt.sh @@ -22,9 +22,5 @@ dnf5 install -y \ micro \ fuse-libs -# --- 2. Die sofortige Bereinigung (WICHTIG!) --- -echo "Cleaning up this layer..." -dnf5 clean all || true -dnf5 autoremove -y || true -rm -rf /tmp/* /var/tmp/* || true + diff --git a/build/40-remove-packages.sh b/build/40-remove-packages.sh index b6f4143..6e9a199 100755 --- a/build/40-remove-packages.sh +++ b/build/40-remove-packages.sh @@ -11,7 +11,7 @@ dnf5 remove -y \ firefox-langpacks* \ plasma-discover \ plasma-discover-flatpak \ - plasma-discover-notifier || true + plasma-discover-notifier rm -f /etc/xdg/autostart/org.kde.discover.notifier.desktop diff --git a/build/50-prepare-flatpak-for-bazaar.sh b/build/50-prepare-flatpak-for-bazaar.sh index 23112ff..edc5125 100644 --- a/build/50-prepare-flatpak-for-bazaar.sh +++ b/build/50-prepare-flatpak-for-bazaar.sh @@ -3,4 +3,4 @@ set -oue pipefail echo "Downloading Flathub repository definition..." mkdir -p /usr/share/flatpak/remotes.d/ -curl -o /usr/share/flatpak/remotes.d/flathub.flatpakrepo https://dl.flathub.org/repo/flathub.flatpakrepo +curl -f --retry 3 --retry-delay 5 -o /usr/share/flatpak/remotes.d/flathub.flatpakrepo https://dl.flathub.org/repo/flathub.flatpakrepo diff --git a/scripts/notify-bootc-user.sh b/scripts/notify-bootc-user.sh index b4e5c1f..9b80e37 100755 --- a/scripts/notify-bootc-user.sh +++ b/scripts/notify-bootc-user.sh @@ -1,13 +1,11 @@ #!/bin/bash set -euo pipefail -# Pfade BOOTC="/usr/bin/bootc" -FLATPAK="/usr/bin/flatpak" +FLATPAK="/usr/bin/flatpak" LOGGER="/usr/bin/logger" LOGINCTL="/usr/bin/loginctl" NOTIFY="/usr/bin/notify-send" -SUDO="/usr/bin/sudo" SYSTEMCTL="/usr/bin/systemctl" TAG="bootc-timer" @@ -16,79 +14,75 @@ TAG="bootc-timer" # Flatpaks im Hintergrund aktualisieren # ============================================================================= $LOGGER -t "$TAG" "Suche nach Flatpak-Updates..." -# || true verhindert den Abbruch, falls Flatpak temporär Netzwerkfehler hat $FLATPAK update -y --noninteractive || $LOGGER -t "$TAG" "Flatpak-Update fehlgeschlagen oder keine Updates vorhanden." # ============================================================================= -# 1. Bootc Upgrade ausführen +# 1. Bootc Upgrade ausfuehren # ============================================================================= $LOGGER -t "$TAG" "Suche nach System-Updates (bootc)..." -# || true ist hier ESSENZIELL, da bootc upgrade bei "keine Updates" je nach Version -# einen Exit-Code ungleich 0 zurückgeben kann, was set -e triggern würde. -$BOOTC upgrade || $LOGGER -t "$TAG" "bootc upgrade beendet (System möglicherweise bereits aktuell)." +$BOOTC upgrade || true # ============================================================================= -# 2. Status-Check (Sicherer Umgang mit jq) +# 2. Pruefen ob ein gestagtes Deployment vorhanden ist # ============================================================================= -# Wir lesen den Status aus und fangen den Wert direkt ab. -# Wenn 'staged' gleich null ist, liefert jq den Text "null". -STAGED_STATUS=$( $BOOTC status --json | jq -r '.status.staged' 2>/dev/null || echo "null" ) - -if [[ "$STAGED_STATUS" == "null" ]]; then - # KEIN Update gefunden - $LOGGER -t "$TAG" "System aktuell (keine gestageden Updates vorhanden)." +# jq -e gibt Exit-Code 1 zurueck wenn das Ergebnis null/false/0/leer ist. +if ! $BOOTC status --json | jq -e '.status.staged != null' > /dev/null 2>&1; then + $LOGGER -t "$TAG" "Kein gestagtes Deployment gefunden (System aktuell oder bereits angewendet)." exit 0 -else - $LOGGER -t "$TAG" "Update gefunden und gestaged. Suche aktiven Desktop-User..." +fi - # ============================================================================= - # 3. Robust den User der AKTIVEN grafischen Sitzung (seat0) ermitteln - # ============================================================================= - # Wir vermeiden die Standard-Pipeline | while read, um Subshell-Probleme zu umgehen. - # Stattdessen nutzen wir ein Process Substitution (< <(...)) - USER_ID="" - while read -r sid rest; do - if [[ -n "$sid" ]]; then - SEAT=$( $LOGINCTL show-session "$sid" -p Seat --value 2>/dev/null || echo "" ) - STATE=$( $LOGINCTL show-session "$sid" -p State --value 2>/dev/null || echo "" ) - - if [[ "$SEAT" == "seat0" ]] && [[ "$STATE" == "active" ]]; then - USER_ID=$( $LOGINCTL show-session "$sid" -p UID --value 2>/dev/null || echo "" ) - break - fi +$LOGGER -t "$TAG" "Update gestaged. Suche aktiven Desktop-User..." + +# ============================================================================= +# 3. Aktiven Desktop-User auf seat0 ermitteln +# ============================================================================= +USER_ID="" +while read -r sid _rest; do + if [[ -n "$sid" ]]; then + SEAT=$($LOGINCTL show-session "$sid" -p Seat --value 2>/dev/null || echo "") + STATE=$($LOGINCTL show-session "$sid" -p State --value 2>/dev/null || echo "") + + if [[ "$SEAT" == "seat0" ]] && [[ "$STATE" == "active" ]]; then + USER_ID=$($LOGINCTL show-session "$sid" -p UID --value 2>/dev/null || echo "") + break fi - done < <($LOGINCTL list-sessions --no-legend) - - if [[ -z "$USER_ID" ]]; then - $LOGGER -t "$TAG" "Update bereit, aber kein aktiver Desktop-User auf seat0 gefunden." - exit 0 fi +done < <($LOGINCTL list-sessions --no-legend) - $LOGGER -t "$TAG" "Sende Benachrichtigung an User-ID: $USER_ID" +if [[ -z "$USER_ID" ]]; then + $LOGGER -t "$TAG" "Update bereit, aber kein aktiver Desktop-User auf seat0 gefunden." + exit 0 +fi - # ============================================================================= - # 4. Benachrichtigung senden - # ============================================================================= - # Wenn der User die Benachrichtigung ignoriert/schließt, gibt notify-send einen - # Exit-Code > 0 zurück. Das "|| echo 'closed'" fängt das sauber ab. - ACTION=$( $SUDO -u "#$USER_ID" env \ - DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/$USER_ID/bus \ - XDG_RUNTIME_DIR=/run/user/$USER_ID \ - $NOTIFY "System-Update bereit" \ +$LOGGER -t "$TAG" "Sende Benachrichtigung an User-ID: $USER_ID" + +# ============================================================================= +# 4. Benachrichtigung senden +# ============================================================================= +# Die D-Bus-Umgebungsvariablen muessen explizit gesetzt werden, da der +# Systemd-Service als root laeuft und keine User-Session erbt. +# notify-send --wait blockiert, bis der User die Benachrichtigung schliesst +# oder einen Action-Button klickt. +ACTION=$( sudo -u "#$USER_ID" \ + env \ + DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/${USER_ID}/bus" \ + XDG_RUNTIME_DIR="/run/user/${USER_ID}" \ + $NOTIFY \ + "System-Update bereit" \ "Ein neues Image wurde heruntergeladen. Jetzt neu starten?" \ --app-name="System-Update" \ --icon=software-update-available \ --urgency=critical \ --action="reboot=Jetzt neu starten" \ - --wait || echo "closed" ) + --wait \ + 2>/dev/null || echo "closed" ) - # ============================================================================= - # 5. Auswertung der User-Aktion - # ============================================================================= - if [[ "$ACTION" == "reboot" ]]; then - $LOGGER -t "$TAG" "User hat Reboot gewählt. Starte System neu..." - $SYSTEMCTL reboot - else - $LOGGER -t "$TAG" "Benachrichtigung wurde geschlossen, ignoriert oder Timeout ($ACTION)." - fi +# ============================================================================= +# 5. Auswertung +# ============================================================================= +if [[ "$ACTION" == "reboot" ]]; then + $LOGGER -t "$TAG" "User hat Reboot gewaehlt. Starte System neu..." + $SYSTEMCTL reboot +else + $LOGGER -t "$TAG" "Benachrichtigung geschlossen oder ignoriert (kein Reboot)." fi