2026-05-01 13:10:33 +02:00
|
|
|
#!/bin/bash
|
2026-05-16 09:31:45 +02:00
|
|
|
set -euo pipefail
|
2026-05-23 11:56:54 +02:00
|
|
|
|
2026-05-14 20:47:53 +02:00
|
|
|
# Pfade
|
2026-05-13 20:24:30 +02:00
|
|
|
BOOTC="/usr/bin/bootc"
|
2026-05-23 12:50:55 +02:00
|
|
|
FLATPAK="/usr/bin/flatpak"
|
2026-05-13 20:24:30 +02:00
|
|
|
LOGGER="/usr/bin/logger"
|
|
|
|
|
LOGINCTL="/usr/bin/loginctl"
|
|
|
|
|
NOTIFY="/usr/bin/notify-send"
|
|
|
|
|
SUDO="/usr/bin/sudo"
|
|
|
|
|
SYSTEMCTL="/usr/bin/systemctl"
|
|
|
|
|
|
|
|
|
|
TAG="bootc-timer"
|
2026-05-01 13:10:33 +02:00
|
|
|
|
2026-05-23 12:50:55 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# Flatpaks im Hintergrund aktualisieren
|
|
|
|
|
# =============================================================================
|
|
|
|
|
$LOGGER -t "$TAG" "Suche nach Flatpak-Updates..."
|
2026-05-24 21:20:17 +02:00
|
|
|
# || true verhindert den Abbruch, falls Flatpak temporär Netzwerkfehler hat
|
|
|
|
|
$FLATPAK update -y --noninteractive || $LOGGER -t "$TAG" "Flatpak-Update fehlgeschlagen oder keine Updates vorhanden."
|
2026-05-23 12:50:55 +02:00
|
|
|
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# 1. Bootc Upgrade ausführen
|
|
|
|
|
# =============================================================================
|
|
|
|
|
$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)."
|
2026-05-03 21:15:43 +02:00
|
|
|
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# 2. Status-Check (Sicherer Umgang mit jq)
|
|
|
|
|
# =============================================================================
|
|
|
|
|
# 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
|
2026-05-17 20:30:06 +02:00
|
|
|
# KEIN Update gefunden
|
2026-05-24 21:20:17 +02:00
|
|
|
$LOGGER -t "$TAG" "System aktuell (keine gestageden Updates vorhanden)."
|
|
|
|
|
exit 0
|
2026-05-16 09:31:45 +02:00
|
|
|
else
|
2026-05-23 11:56:54 +02:00
|
|
|
$LOGGER -t "$TAG" "Update gefunden und gestaged. Suche aktiven Desktop-User..."
|
|
|
|
|
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
2026-05-23 11:56:54 +02:00
|
|
|
# 3. Robust den User der AKTIVEN grafischen Sitzung (seat0) ermitteln
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# 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
|
2026-05-23 11:56:54 +02:00
|
|
|
fi
|
2026-05-24 21:20:17 +02:00
|
|
|
done < <($LOGINCTL list-sessions --no-legend)
|
2026-05-11 17:47:32 +02:00
|
|
|
|
2026-05-14 20:47:53 +02:00
|
|
|
if [[ -z "$USER_ID" ]]; then
|
2026-05-23 11:56:54 +02:00
|
|
|
$LOGGER -t "$TAG" "Update bereit, aber kein aktiver Desktop-User auf seat0 gefunden."
|
2026-05-14 20:47:53 +02:00
|
|
|
exit 0
|
|
|
|
|
fi
|
|
|
|
|
|
2026-05-23 11:56:54 +02:00
|
|
|
$LOGGER -t "$TAG" "Sende Benachrichtigung an User-ID: $USER_ID"
|
|
|
|
|
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# 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.
|
2026-05-23 11:56:54 +02:00
|
|
|
ACTION=$( $SUDO -u "#$USER_ID" env \
|
2026-05-14 20:47:53 +02:00
|
|
|
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?" \
|
2026-05-17 21:10:24 +02:00
|
|
|
--app-name="System-Update" \
|
2026-05-14 20:47:53 +02:00
|
|
|
--icon=software-update-available \
|
|
|
|
|
--urgency=critical \
|
|
|
|
|
--action="reboot=Jetzt neu starten" \
|
2026-05-23 11:56:54 +02:00
|
|
|
--wait || echo "closed" )
|
2026-05-14 20:47:53 +02:00
|
|
|
|
2026-05-24 21:20:17 +02:00
|
|
|
# =============================================================================
|
|
|
|
|
# 5. Auswertung der User-Aktion
|
|
|
|
|
# =============================================================================
|
2026-05-14 20:47:53 +02:00
|
|
|
if [[ "$ACTION" == "reboot" ]]; then
|
2026-05-23 11:56:54 +02:00
|
|
|
$LOGGER -t "$TAG" "User hat Reboot gewählt. Starte System neu..."
|
2026-05-14 20:47:53 +02:00
|
|
|
$SYSTEMCTL reboot
|
2026-05-23 11:56:54 +02:00
|
|
|
else
|
2026-05-24 21:20:17 +02:00
|
|
|
$LOGGER -t "$TAG" "Benachrichtigung wurde geschlossen, ignoriert oder Timeout ($ACTION)."
|
2026-05-11 17:47:32 +02:00
|
|
|
fi
|
2026-05-01 13:10:33 +02:00
|
|
|
fi
|