diff --git a/multi-watch.sh b/multi-watch.sh new file mode 100644 index 0000000..4493d6e --- /dev/null +++ b/multi-watch.sh @@ -0,0 +1,127 @@ +#!/bin/bash + +CONFIG_DIR="/config" +CONFIG_FILE="$CONFIG_DIR/watchdog.conf" +STATE_FILE="$CONFIG_DIR/watch_state.json" + +if [ ! -f "$STATE_FILE" ] || ! jq -e . "$STATE_FILE" >/dev/null 2>&1; then + echo "{}" > "$STATE_FILE" +fi + +while true; do + if [ -f "$CONFIG_FILE" ]; then + source "$CONFIG_FILE" + else + echo "❌ Fehler: $CONFIG_FILE nicht gefunden!" + sleep 60; continue + fi + + cat < /etc/msmtprc +defaults +auth on +tls on +tls_starttls off +tls_trust_file /etc/ssl/certs/ca-certificates.crt +account default +host $SMTP_HOST +port $SMTP_PORT +from $EMAIL_FROM +user $SMTP_USER +password $SMTP_PASS +EOF + chmod 600 /etc/msmtprc + + INTERVAL=${CHECK_INTERVAL:-3600} + UPDATES_FOUND="" + VALID_KEYS=() + echo "--- Starte Check: $(date) ---" + + for entry in "${TARGETS[@]}"; do + IFS="|" read -r TYPE REPO EXTRA <<< "$entry" + + CLEAN_REPO_NAME=$(echo "$REPO" | sed -E 's/\/\/[^@]+@/\/\//') + KEY="${TYPE}_${CLEAN_REPO_NAME//[\/\.:]/_}_${EXTRA}" + VALID_KEYS+=("$KEY") + + OLD_VAL=$(jq -r ".[\"$KEY\"] // empty" "$STATE_FILE") + NEW_VAL="" + + echo "Prüfe $TYPE: $CLEAN_REPO_NAME:$EXTRA..." + + if [ "$TYPE" == "DOCKER" ]; then + if [[ "$REPO" != *"."* ]] || [[ "$REPO" == *"docker.io"* ]]; then + CLEAN_HUB=${REPO#docker.io/} + [[ "$CLEAN_HUB" != *"/"* ]] && CLEAN_HUB="library/$CLEAN_HUB" + NEW_VAL=$(curl -s "https://hub.docker.com/v2/repositories/${CLEAN_HUB}/tags/${EXTRA}" | jq -r '.last_updated // empty') + else + REG_HOST=$(echo $REPO | cut -d/ -f1) + IMG_NAME=$(echo $REPO | cut -d/ -f2-) + TOKEN=$(curl -s "https://${REG_HOST}/v2/token?service=${REG_HOST}&scope=repository:${IMG_NAME}:pull" | jq -r '.token // empty') + [[ -n "$TOKEN" && "$TOKEN" != "null" ]] && AUTH_H="Authorization: Bearer $TOKEN" || AUTH_H="X-No-Auth: true" + RESPONSE=$(curl -s -i -L -H "$AUTH_H" -H "Accept: application/vnd.docker.distribution.manifest.v2+json" "https://${REG_HOST}/v2/${IMG_NAME}/manifests/${EXTRA}") + NEW_VAL=$(echo "$RESPONSE" | grep -i "docker-content-digest" | awk '{print $2}' | tr -d '\r') + [[ -z "$NEW_VAL" ]] && NEW_VAL=$(echo "$RESPONSE" | grep -i "etag" | awk '{print $2}' | tr -d '\r' | tr -d '"') + fi + elif [ "$TYPE" == "GITHUB" ] || [ "$TYPE" == "GIT" ]; then + if [[ "$REPO" =~ ^http ]] || [[ "$REPO" == *"."* ]]; then + URL="$REPO" + [[ ! "$URL" =~ ^http ]] && URL="https://$URL" + NEW_VAL=$(GIT_TERMINAL_PROMPT=0 timeout 15s git ls-remote "$URL" "refs/heads/$EXTRA" 2>/dev/null | awk '{print $1}') + if [ $? -ne 0 ] || [ -z "$NEW_VAL" ]; then echo " ⚠️ Git Fehler."; continue; fi + else + NEW_VAL=$(curl -s "https://api.github.com/repos/${REPO}/branches/${EXTRA}" | jq -r '.commit.sha // empty') + fi + fi + + if [ -z "$NEW_VAL" ] || [ "$NEW_VAL" == "null" ]; then continue; fi + + if [ -z "$OLD_VAL" ] || [ "$OLD_VAL" != "$NEW_VAL" ]; then + if [ -z "$OLD_VAL" ]; then + echo " 🆕 Neuaufnahme." + else + # HIER DIE ÄNDERUNG: Typ voranstellen + MSG="[$TYPE] Update für: $CLEAN_REPO_NAME ($EXTRA)" + echo " 🔔 $MSG" + # Wir fügen einen Zeilenumbruch für die Mail hinzu + UPDATES_FOUND="${UPDATES_FOUND}${MSG}\n" + fi + # Speichern... + NEW_JSON=$(jq ".[\"$KEY\"] = \"$NEW_VAL\"" "$STATE_FILE" 2>/dev/null) + echo "$NEW_JSON" > "${STATE_FILE}.tmp" && mv "${STATE_FILE}.tmp" "$STATE_FILE" + else + echo " ✅ Aktuell." + fi + done + + echo "Säubere veraltete Einträge..." + VALID_KEYS_JSON=$(printf '%s\n' "${VALID_KEYS[@]}" | jq -R . | jq -s .) + CLEAN_JSON=$(jq "with_entries(select(.key as \$k | $VALID_KEYS_JSON | index(\$k)))" "$STATE_FILE") + echo "$CLEAN_JSON" > "$STATE_FILE" + + # Mail Versand + if [ -n "$UPDATES_FOUND" ]; then + echo " 📧 Sende Benachrichtigung an $EMAIL_TO..." + + ( + echo "To: $EMAIL_TO" + echo "Subject: Watchdog Update Alert" + echo "Content-Type: text/plain; charset=utf-8" + echo "Content-Transfer-Encoding: 8bit" + echo "" + echo "Der Watchdog hat folgende Updates gefunden:" + echo "------------------------------------------" + echo -e "$UPDATES_FOUND" + echo "------------------------------------------" + echo "Check beendet am: $(date)" + ) | timeout 30s msmtp "$EMAIL_TO" + + if [ $? -eq 0 ]; then + echo " ✅ E-Mail erfolgreich versendet." + else + echo " ❌ E-Mail Versand fehlgeschlagen!" + fi + fi + + echo "Check beendet. Nächster Scan in $INTERVAL s." + sleep "$INTERVAL" +done \ No newline at end of file