#!/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="" log() { local msg="$1" echo "[$(date '+%F %T')] $msg" | tee -a "$LOG" } send_telegram() { local text="$1" local http_code http_code="$(curl -sS --show-error \ -o /tmp/pingu-telegram-response.txt \ -w '%{http_code}' \ -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \ --data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \ --data-urlencode "text=${text}")" cat /tmp/pingu-telegram-response.txt >> "$LOG" echo >> "$LOG" if [ "$http_code" -ne 200 ]; then log "Telegram-API Fehler, HTTP ${http_code}" return 1 fi } cleanup_on_error() { local exit_code=$? local line_no="${1:-unknown}" log "FEHLER in Zeile ${line_no}, Exit-Code ${exit_code}" curl -sS -X POST "https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage" \ --data-urlencode "chat_id=${TELEGRAM_CHAT_ID}" \ --data-urlencode "text=❌ ${HOST}: Update-Script fehlgeschlagen in Zeile ${line_no} (Exit ${exit_code})." \ >> "$LOG" 2>&1 || true exit "$exit_code" } trap 'cleanup_on_error ${LINENO}' ERR check_docker_updates() { if ! command -v docker >/dev/null 2>&1; then log "Docker nicht installiert - überspringe Container-Prüfung" return 0 fi if ! docker info >/dev/null 2>&1; then log "Docker-Daemon nicht erreichbar - überspringe Container-Prüfung" return 0 fi local container_ids mapfile -t container_ids < <(docker ps -q) if [ "${#container_ids[@]}" -eq 0 ]; then log "Keine laufenden Docker-Container gefunden" return 0 fi log "Prüfe ${#container_ids[@]} laufende Docker-Container auf Image-Updates" local cid name image running_id latest_id pull_output for cid in "${container_ids[@]}"; do name="$(docker inspect --format '{{.Name}}' "$cid" | sed 's#^/##')" image="$(docker inspect --format '{{.Config.Image}}' "$cid")" running_id="$(docker inspect --format '{{.Image}}' "$cid")" log "Prüfe Container ${name} mit Image ${image}" if pull_output="$(docker pull "$image" 2>&1)"; then latest_id="$(docker image inspect --format '{{.Id}}' "$image")" if [ "$running_id" != "$latest_id" ]; then DOCKER_UPDATES=$((DOCKER_UPDATES + 1)) DOCKER_UPDATE_LIST+=$'\n'"🐳 ${name} (${image})" log "Update verfügbar für ${name}" else log "Kein Update für ${name}" fi else log "Konnte Image ${image} für ${name} nicht prüfen: ${pull_output}" fi done } main() { touch "$LOG" chmod 600 "$LOG" log "=== Update Start ${HOST} ===" export DEBIAN_FRONTEND=noninteractive log "Starte apt-get update" apt-get update >> "$LOG" 2>&1 log "Starte apt-get upgrade" apt-get -y upgrade >> "$LOG" 2>&1 if [ -f /var/run/reboot-required ]; then REBOOT=1 log "Reboot erforderlich" else log "Kein Reboot erforderlich" fi check_docker_updates local msg="🐧 ${HOST}: Updates installiert." if [ "$REBOOT" -eq 1 ]; then msg="${msg} REBOOT erforderlich." else msg="${msg} Kein Reboot nötig." fi if [ "$DOCKER_UPDATES" -gt 0 ]; then msg+=$'\n\n'"🐳 Docker-Updates verfügbar: ${DOCKER_UPDATES}${DOCKER_UPDATE_LIST}" else msg+=$'\n\n'"🐳 Docker-Container aktuell." fi log "Sende Telegram-Nachricht" send_telegram "$msg" log "$msg" log "=== Update Ende ${HOST} ===" if [ "$REBOOT" -eq 1 ]; then log "System wird neu gestartet" reboot fi } main "$@"