#!/bin/bash set -Eeuo pipefail HOST="$(hostname)" LOG="/opt/pingu/logs/update.log" TELEGRAM_TOKEN="${TELEGRAM_TOKEN:-8101319618:AAHboFVVgmLPccJB0MDr_R2g0K90hkGqkRw}" TELEGRAM_CHAT_ID="${TELEGRAM_CHAT_ID:-581059353}" REBOOT=0 DOCKER_UPDATES=0 DOCKER_UPDATE_LIST="" DOCKER_MSG="" PIHOLE_INSTALLED=0 PIHOLE_UPDATED=0 PIHOLE_MSG="" log() { echo "[$(date '+%F %T')] $1" | tee -a "$LOG" } send_telegram() { local text="$1" curl -sS -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \ --data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \ --data-urlencode "text=${text}" \ >> "$LOG" 2>&1 || true } cleanup_on_error() { local exit_code=$? log "❌ Fehler in Zeile ${1:-unknown} (Exit ${exit_code})" send_telegram "❌ ${HOST}: Update fehlgeschlagen (Zeile ${1:-?}, Exit ${exit_code})" exit "$exit_code" } trap 'cleanup_on_error ${LINENO}' ERR check_docker_updates() { if ! command -v docker >/dev/null 2>&1; then DOCKER_MSG="🚫 Docker: nicht installiert" return fi if ! docker info >/dev/null 2>&1; then DOCKER_MSG="⚠️ Docker: Daemon nicht erreichbar" return fi local containers mapfile -t containers < <(docker ps -q) if [ "${#containers[@]}" -eq 0 ]; then DOCKER_MSG="🐳 Docker: keine Container aktiv" return fi for cid in "${containers[@]}"; do local name image running_id latest_id name="$(docker inspect --format '{{.Name}}' "$cid" | sed 's#^/##')" image="$(docker inspect --format '{{.Config.Image}}' "$cid")" running_id="$(docker inspect --format '{{.Image}}' "$cid")" docker pull "$image" >/dev/null 2>&1 || continue latest_id="$(docker image inspect --format '{{.Id}}' "$image" 2>/dev/null || true)" if [[ -n "$latest_id" && "$running_id" != "$latest_id" ]]; then DOCKER_UPDATES=$((DOCKER_UPDATES + 1)) DOCKER_UPDATE_LIST+=$'\n'"🐳 ${name} (${image})" fi done if [ "$DOCKER_UPDATES" -gt 0 ]; then DOCKER_MSG="🐳 Docker Updates: ${DOCKER_UPDATES}${DOCKER_UPDATE_LIST}" else DOCKER_MSG="🐳 Docker: aktuell" fi } check_pihole_update() { if ! command -v pihole >/dev/null 2>&1; then PIHOLE_MSG="" return fi PIHOLE_INSTALLED=1 log "Pi-hole detected β†’ checking update" local output if output="$(pihole -up 2>&1)"; then if echo "$output" | grep -q "Everything is up to date"; then PIHOLE_MSG="🧱 Pi-hole: aktuell" else PIHOLE_UPDATED=1 PIHOLE_MSG="🧱 Pi-hole: Update durchgefΓΌhrt" fi else PIHOLE_MSG="❌ Pi-hole: Update fehlgeschlagen" log "$output" fi } # Pihole Check if [ "$PIHOLE_INSTALLED" -eq 1 ]; then if ! pihole status | grep -q "enabled"; then PIHOLE_MSG="❌ Pi-hole: lΓ€uft nicht korrekt" fi fi main() { mkdir -p "$(dirname "$LOG")" touch "$LOG" log "=== Update Start ${HOST} ===" export DEBIAN_FRONTEND=noninteractive log "APT Update" apt-get update 2>&1 | tee -a "$LOG" log "APT Upgrade" apt-get -y upgrade 2>&1 | tee -a "$LOG" if [ -f /var/run/reboot-required ]; then REBOOT=1 log "Reboot erforderlich" fi check_docker_updates check_pihole_update local msg msg=$(cat <