From 8d05d3bc489af81e457a6c7206171b971f8af6d7 Mon Sep 17 00:00:00 2001 From: mm Date: Sun, 13 Sep 2026 23:44:02 +0200 Subject: [PATCH] feat(updater): --check/--version, --force-update mit Rollback, --update-only, systemd-Timer + Windows-Task; VERSION+SHA-Marker; envsubst-Fallback --- README.md | 73 +++++++++++++ install.ps1 | 94 +++++++++++++++- install.sh | 303 +++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 464 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 9eb47c9..99f5ac7 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,79 @@ Der Ausgang läuft über den **NetBird-Reverse-Proxy** (`imac-prometheus.x05.idx mit **Bearer-Token** — dadurch funktioniert der Installer auch auf Maschinen, die **kein NetBird-Peer** sind (Büro-LAN, Kundenlaptop, CGNAT, VM ohne Client). +## Auto-Updater und Force-Updater + +Der Installer hält sich auf den Nodes selbst aktuell. + +### Prüfen + +```sh +sh install.sh --version # installierte + verfügbare Version +sh install.sh --check # Exit 0 = aktuell, Exit 10 = Update verfügbar +``` + +Beides braucht **keinen Token** und **kein root** — gut für Monitoring-Checks. + +### Auto-Updater (systemd-Timer) + +```sh +sh install.sh --name --token --install-update-timer daily +sh install.sh --name --token --install-update-timer 30min +sh install.sh --name --token --install-update-timer weekly +``` + +Legt `telegraf-installer-update.timer` an (Default `daily` 04:30, ±15 min Streuung). +Der Lauf ist billig: Es werden nur `VERSION` und der SHA des Installers verglichen. +Erst bei Abweichung lädt er den Installer und ruft sich mit `--update-only` auf. +Log: `/var/log/telegraf-installer-update.log`. + +`--update-only` fasst **nur** `telegraf.d/`-Konfs und Hilfsscripts an: kein +Paket-Update, `/etc/default/telegraf` (und damit der Token) bleibt unberührt, +kein Neustart wenn sich nichts geändert hat. + +Warum Version **und** Hash: Die `VERSION` erkennt neue Auslieferungen, der SHA +auch Korrekturen ohne Versionssprung (z. B. ein Fix an `journal-tail.sh`). +Ohne den Hash bliebe eine Node mit fehlerhaftem Script stehen. + +### Force-Updater + +```sh +sh install.sh --force-update --name --token +``` + +Schreibt Konfs und Scripts **immer** neu, sichert sie vorher nach +`/var/backups/telegraf-/` und startet den Dienst neu. Schlägt der +Konfig-Test fehl, wird automatisch zurückgerollt. Idempotent — mehrfaches +Ausführen ist folgenlos. Das Werkzeug nach einem kaputten Update oder wenn +jemand Dateien von Hand verändert hat. + +Entfernen: `sh install.sh --remove-update-timer` + +### Windows + +```powershell +.\install.ps1 -Name -Token -Check # Versionsvergleich +.\install.ps1 -Name -Token -InstallUpdateTask # taeglich +.\install.ps1 -Name -Token -InstallUpdateTask -UpdateInterval hourly +.\install.ps1 -Name -Token -ForceUpdate +.\install.ps1 -RemoveUpdateTask +``` + +Die Aufgabe `\NetBirdTelegraf\Update` läuft mit denselben Semantiken +(Version + Hash, nur bei Änderung). Log: +`%ProgramData%\netbird-telegraf\update.log`. + +### Marker auf der Node + +| Datei | Inhalt | +|---|---| +| `/etc/telegraf/CONFIG_VERSION` | zuletzt installierte Repo-Version | +| `/etc/telegraf/INSTALLER_SHA` | SHA256 des Installers zum Installationszeitpunkt | +| `/etc/telegraf/REPO_RAW` | genutzte Repo-Quelle (GitHub-Mirror, Testserver) | + +`REPO_RAW` ist per Umgebungsvariable überschreibbar — nützlich für Tests, +Mirrors oder einen eigenen Fork. + ### Docker-Nodes (kein journalctl im Image) Läuft Telegraf als **Container** (offizielles `telegraf`-Image), ist der Journal-Weg nicht möglich: das Image ist Debian ohne `systemd` und hat **kein `journalctl`**; `/hostfs` ist zudem read-only. Dafür gibt es `scripts/syslog-tail.sh` — es liest die **Syslog-Dateien des Hosts** unter `/hostfs/var/log/`. diff --git a/install.ps1 b/install.ps1 index fa7a221..4bc4bc4 100644 --- a/install.ps1 +++ b/install.ps1 @@ -13,7 +13,12 @@ param( [string]$Collector = "", [string]$Token = "", [string]$Version = "1.40.0", - [switch]$Uninstall + [switch]$Uninstall, + [switch]$Check, # nur Versionsvergleich + [switch]$ForceUpdate, # Confs immer neu schreiben + Dienst neu starten + [switch]$InstallUpdateTask, # geplante Aufgabe fuer Auto-Update + [switch]$RemoveUpdateTask, + [string]$UpdateInterval = "daily" ) $ErrorActionPreference = "Stop" if (-not $Token -and -not $Collector) { throw "Kein Token: -Token angeben (siehe README)." } @@ -38,6 +43,29 @@ if ($Uninstall) { $arch = "amd64" if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { $arch = "arm64" } elseif (-not [Environment]::Is64BitOperatingSystem) { $arch = "i386" } +$RepoRaw = if ($env:REPO_RAW) { $env:REPO_RAW } else { "https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main" } +$MarkerDir = "$env:ProgramData\netbird-telegraf" +$VersionFile = Join-Path $MarkerDir "CONFIG_VERSION" + +function Get-RemoteVersion { + try { return (Invoke-WebRequest -UseBasicParsing -TimeoutSec 15 "$RepoRaw/VERSION").Content.Trim() } + catch { return "" } +} + +# Reine Abfragen: kein Token, kein Dienst-Eingriff +if ($Check -or (-not $Token -and -not $Uninstall -and -not $RemoveUpdateTask)) { + $local = if (Test-Path $VersionFile) { (Get-Content $VersionFile -Raw).Trim() } else { "nicht installiert" } + $remote = Get-RemoteVersion + if (-not $remote) { $remote = "nicht erreichbar" } + Write-Host "installiert: $local" + Write-Host "verfuegbar: $remote" + if ($Check) { + if ($local -eq $remote -and $local -ne "nicht installiert") { Write-Host "Status: aktuell"; exit 0 } + Write-Host "Status: Update verfuegbar"; exit 10 + } + if (-not $Token) { Write-Host "[netbird-telegraf] Kein Token angegeben (-Token)."; exit 2 } +} + Write-Host "[netbird-telegraf] Node=$Name Arch=$arch Collector=$Collector" try { @@ -125,5 +153,69 @@ Stop-Service telegraf -ErrorAction SilentlyContinue Start-Service telegraf Start-Sleep -Seconds 3 if ((Get-Service telegraf).Status -ne "Running") { throw "Dienst telegraf läuft nicht." } + +# --- Versionsmarker fuer den Auto-Updater --- +New-Item -ItemType Directory -Force -Path $MarkerDir | Out-Null +$rv = Get-RemoteVersion +if (-not $rv) { $rv = "unbekannt" } +Set-Content -Path $VersionFile -Value $rv -Encoding ASCII +$iscript = Join-Path $env:TEMP "tg-installer.ps1" +try { + Invoke-WebRequest -UseBasicParsing -TimeoutSec 25 "$RepoRaw/install.ps1" -OutFile $iscript + (Get-FileHash $iscript -Algorithm SHA256).Hash.ToLower() | Set-Content -Path (Join-Path $MarkerDir "INSTALLER_SHA") -Encoding ASCII +} catch { } +Set-Content -Path (Join-Path $MarkerDir "REPO_RAW") -Value $RepoRaw -Encoding ASCII + +# --- Auto-Update als geplante Aufgabe --- +function Install-UpdateTask { + param([string]$Interval) + $upd = Join-Path $MarkerDir "update.ps1" + $body = @" +`$ErrorActionPreference = 'Continue' +`$log = '`$env:ProgramData\netbird-telegraf\update.log' +function Say(`$m) { Add-Content -Path `$log -Value ("{0} {1}" -f (Get-Date -Format s), `$m) } +`$repo = if (`$env:REPO_RAW) { `$env:REPO_RAW } else { (Get-Content '`$env:ProgramData\netbird-telegraf\REPO_RAW' -Raw).Trim() } +`$vf = '`$env:ProgramData\netbird-telegraf\CONFIG_VERSION' +`$local = if (Test-Path `$vf) { (Get-Content `$vf -Raw).Trim() } else { '' } +`$remote = '' +try { `$remote = (Invoke-WebRequest -UseBasicParsing -TimeoutSec 20 "`$repo/VERSION").Content.Trim() } catch { } +if (-not `$remote) { Say 'Repo nicht erreichbar — kein Update.'; exit 0 } +`$need = (`$local -ne `$remote) +if (-not `$need) { + try { + `$t = Join-Path `$env:TEMP 'tg-i.ps1' + Invoke-WebRequest -UseBasicParsing -TimeoutSec 25 "`$repo/install.ps1" -OutFile `$t + `$rs = (Get-FileHash `$t -Algorithm SHA256).Hash.ToLower() + `$ls = (Get-Content '`$env:ProgramData\netbird-telegraf\INSTALLER_SHA' -Raw -ErrorAction SilentlyContinue).Trim() + if (`$rs -ne `$ls) { `$need = `$true } + } catch { } +} +if (-not `$need) { Say "aktuell (`$local) — nichts zu tun."; exit 0 } +Say "Update `$local -> `$remote" +`$i = Join-Path `$env:TEMP 'tg-i.ps1' +try { Invoke-WebRequest -UseBasicParsing -TimeoutSec 60 "`$repo/install.ps1" -OutFile `$i } catch { Say 'Download fehlgeschlagen.'; exit 1 } +`$nm = (Get-Content '`$env:ProgramData\netbird-telegraf\NODE_NAME' -Raw -ErrorAction SilentlyContinue).Trim() +`$tk = (Get-Content '`$env:ProgramData\netbird-telegraf\TOKEN' -Raw -ErrorAction SilentlyContinue).Trim() +try { + & powershell -NoProfile -ExecutionPolicy Bypass -File `$i -Name `$nm -Token `$tk *>> `$log + Say 'Update erfolgreich.' +} catch { Say "Update FEHLGESCHLAGEN: `$_" } +"@ + Set-Content -Path $upd -Value $body -Encoding UTF8 + $when = switch ($Interval) { "hourly" { (New-ScheduledTaskTrigger -Once -At (Get-Date) -RepetitionInterval (New-TimeSpan -Hours 1)) } + "weekly" { (New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 4:30am) } + default { (New-ScheduledTaskTrigger -Daily -At 4:30am) } } + $act = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$upd`"" + $set = New-ScheduledTaskSettingsSet -StartWhenAvailable -DontStopOnIdleEnd + Register-ScheduledTask -TaskName "NetBirdTelegraf-Update" -TaskPath "\NetBirdTelegraf\" -Trigger $when -Action $act -Settings $set -Force | Out-Null + Write-Host "[netbird-telegraf] Auto-Update-Aufgabe aktiv ($Interval) — Log: $MarkerDir\update.log" +} + +if ($ForceUpdate) { Write-Host "[netbird-telegraf] Force-Update: Konfiguration wurde neu geschrieben." } +if ($InstallUpdateTask) { Install-UpdateTask -Interval $UpdateInterval } +if ($RemoveUpdateTask) { + Unregister-ScheduledTask -TaskName "NetBirdTelegraf-Update" -TaskPath "\NetBirdTelegraf\" -Confirm:$false -ErrorAction SilentlyContinue + Write-Host "[netbird-telegraf] Auto-Update-Aufgabe entfernt." +} Write-Host "[netbird-telegraf] OK — Node '$Name' liefert an $PromUrl (Metriken) und $LokiUrl (Eventlog Warn/Error)." Write-Host "[netbird-telegraf] Grafana: http://100.83.134.46:3000 (nur im NetBird)" diff --git a/install.sh b/install.sh index 51272f3..df6c861 100755 --- a/install.sh +++ b/install.sh @@ -22,6 +22,14 @@ # --pve-url PVE-API-URL (Default: https://127.0.0.1:8006/api2/json) # --apache-log

Apache-Access-Log (Default: /var/log/apache2/access.log) # --uninstall Telegraf + Konfiguration entfernen +# --check Nur Versionsvergleich, nichts aendern (Exit 0 = aktuell) +# --version Installierte und verfuegbare Version ausgeben +# --force-update Confs/Scripts IMMER neu schreiben + Dienst neu starten +# --update-only Nur Confs/Scripts aktualisieren (kein Paket, kein Restart +# ohne Aenderung) — wird vom Auto-Updater-Timer genutzt +# --install-update-timer [daily|hourly|weekly|min] +# systemd-Timer fuer den Auto-Updater einrichten +# --remove-update-timer Timer wieder entfernen # ============================================================================ set -eu @@ -38,8 +46,15 @@ PVE_NODE="${PVE_NODE:-}" PVE_URL="${PVE_URL:-}" APACHE_LOG="/var/log/apache2/access.log" TELEGRAF_VERSION="${TELEGRAF_VERSION:-1.40.0}" -REPO_RAW="https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main" +# Ueberschreibbar (Tests/Mirror): REPO_RAW=... sh install.sh +REPO_RAW="${REPO_RAW:-https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main}" UNINSTALL=0 +CHECK=0 +SHOW_VERSION=0 +FORCE_UPDATE=0 +UPDATE_ONLY=0 +TIMER_INTERVAL="" +REMOVE_TIMER=0 while [ $# -gt 0 ]; do case "$1" in @@ -52,6 +67,17 @@ while [ $# -gt 0 ]; do --pve-url) PVE_URL="$2"; shift 2 ;; --apache-log) APACHE_LOG="$2"; shift 2 ;; --uninstall) UNINSTALL=1; shift ;; + --check) CHECK=1; shift ;; + --version) SHOW_VERSION=1; shift ;; + --force-update) FORCE_UPDATE=1; shift ;; + --update-only) UPDATE_ONLY=1; shift ;; + --install-update-timer) + TIMER_INTERVAL="${2:-daily}" + case "$TIMER_INTERVAL" in + daily|hourly|weekly|[0-9]*min|[0-9]*) shift 2 ;; + *) TIMER_INTERVAL="daily"; shift ;; + esac ;; + --remove-update-timer) REMOVE_TIMER=1; shift ;; -h|--help) sed -n '2,24p' "$0"; exit 0 ;; *) echo "Unbekannte Option: $1" >&2; exit 2 ;; esac @@ -61,6 +87,19 @@ log() { printf '\033[1;34m[netbird-telegraf]\033[0m %s\n' "$*"; } die() { printf '\033[1;31m[netbird-telegraf] FEHLER:\033[0m %s\n' "$*" >&2; exit 1; } [ "$(id -u)" -eq 0 ] || die "Bitte als root ausführen (sudo)." +# Reine Abfragen brauchen keinen Token und kein root (Timer-Verwaltung schon). +if [ "$SHOW_VERSION" -eq 1 ] || [ "$CHECK" -eq 1 ]; then + LOCAL_V="$(cat /etc/telegraf/CONFIG_VERSION 2>/dev/null || echo 'nicht installiert')" + REMOTE_V="$(curl -fsS -m 15 "$REPO_RAW/VERSION" 2>/dev/null | tr -d ' \r\n')" + [ -n "$REMOTE_V" ] || REMOTE_V="nicht erreichbar" + printf 'installiert: %s\nverfuegbar: %s\n' "$LOCAL_V" "$REMOTE_V" + [ "$CHECK" -eq 1 ] || exit 0 + if [ "$LOCAL_V" = "$REMOTE_V" ] && [ -n "$LOCAL_V" ] && [ "$LOCAL_V" != "nicht installiert" ]; then + echo "Status: aktuell"; exit 0 + fi + echo "Status: Update verfuegbar"; exit 10 +fi + [ -n "$TELEGRAF_TOKEN" ] || die "Kein Token: --token angeben (siehe README)." if [ -n "${COLLECTOR:-}" ]; then @@ -129,6 +168,20 @@ if command -v curl >/dev/null; then fi fi +# -------------------------------------------------------------------------- +# Update-Only: nur Konfiguration und Hilfsscripts aktualisieren. +# Kein Paket installieren, /etc/default/telegraf unangetastet lassen (Token!), +# Dienst nur neu starten, wenn sich wirklich etwas geaendert hat. +# -------------------------------------------------------------------------- +SNAPSHOT_BEFORE="" +if [ "$UPDATE_ONLY" -eq 1 ]; then + SNAPSHOT_BEFORE="$(mktemp)" + cat /etc/telegraf/telegraf.d/*.conf /etc/telegraf/telegraf.conf 2>/dev/null > "$SNAPSHOT_BEFORE" || true + for s in journal-tail syslog-tail node-info proxmox-ve gpu-rocm; do + [ -f "/etc/telegraf/$s.sh" ] && cat "/etc/telegraf/$s.sh" >> "$SNAPSHOT_BEFORE" 2>/dev/null + done +fi + # -------------------------------------------------------------------------- # Installation # -------------------------------------------------------------------------- @@ -196,6 +249,7 @@ EOF if command -v telegraf >/dev/null 2>&1 || [ -x /usr/local/bin/telegraf ]; then log "Telegraf bereits installiert ($(telegraf --version 2>/dev/null || /usr/local/bin/telegraf --version))." + [ "$UPDATE_ONLY" -eq 1 ] && log "Update-Only: Paketinstallation uebersprungen." else case "$OS_ID" in debian|ubuntu|raspbian|linuxmint|pop) install_apt ;; @@ -222,6 +276,9 @@ mkdir -p /etc/telegraf/telegraf.d /etc/default umask 077 cat > /etc/default/telegraf < "$_dst.tmp" && mv "$_dst.tmp" "$_dst" + done +} + # Holt eine Conf und ersetzt ${...}-Platzhalter aus /etc/default/telegraf. fetch_conf() { fetch "$1" "$2.tmp" set -a; [ -r /etc/default/telegraf ] && . /etc/default/telegraf; set +a - envsubst '${NODE_NAME} ${PROM_URL} ${LOKI_URL} ${TELEGRAF_TOKEN} ${PVE_TOKEN} ${PVE_NODE} ${PVE_URL} ${APACHE_LOG}' < "$2.tmp" > "$2" + if command -v envsubst >/dev/null; then + envsubst '${NODE_NAME} ${PROM_URL} ${LOKI_URL} ${TELEGRAF_TOKEN} ${PVE_TOKEN} ${PVE_NODE} ${PVE_URL} ${APACHE_LOG}' < "$2.tmp" > "$2" + else + subst_vars "$2.tmp" "$2" NODE_NAME PROM_URL LOKI_URL TELEGRAF_TOKEN PVE_TOKEN PVE_NODE PVE_URL APACHE_LOG + fi if grep -q '\${' "$2"; then log "WARNUNG: $2 enthaelt noch unaufgeloeste Platzhalter:" grep -o '\${[A-Z_]*}' "$2" | sort -u >&2 @@ -334,10 +410,47 @@ EOF esac chown -R telegraf:telegraf /etc/telegraf 2>/dev/null || true +# -------------------------------------------------------------------------- +# Force-Update: Confs und Hilfsscripts erzwungen neu schreiben. +# Laeuft VOR dem Konfig-Test, damit ein Rollback unten greifen kann. +# -------------------------------------------------------------------------- +write_conf_backups() { # Sicherung fuer den Rollback + BK="/var/backups/telegraf-$(date +%Y%m%d-%H%M%S)" + mkdir -p "$BK" + cp -a /etc/telegraf/telegraf.d "$BK/" 2>/dev/null || true + cp -a /etc/telegraf/telegraf.conf "$BK/" 2>/dev/null || true + printf '%s' "$BK" > /var/lib/telegraf-last-backup +} + +rollback_conf() { # letzte Sicherung zurueckspielen + BK="$(cat /var/lib/telegraf-last-backup 2>/dev/null || true)" + [ -n "$BK" ] && [ -d "$BK/telegraf.d" ] || return 1 + rm -rf /etc/telegraf/telegraf.d + cp -a "$BK/telegraf.d" /etc/telegraf/telegraf.d + [ -f "$BK/telegraf.conf" ] && cp -a "$BK/telegraf.conf" /etc/telegraf/telegraf.conf + log "Rollback aus $BK" +} + +if [ "$FORCE_UPDATE" -eq 1 ]; then + write_conf_backups + log "Force-Update: Confs und Scripts werden neu geschrieben." +fi + # Konfig testen TG="$(command -v telegraf || echo /usr/local/bin/telegraf)" set -a; . /etc/default/telegraf; set +a -"$TG" --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --test --input-filter cpu:mem >/dev/null 2>&1 || die "Konfiguration ungültig — telegraf --test prüfen." +if ! "$TG" --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --test --input-filter cpu:mem >/dev/null 2>&1; then + # Bei Force-/Auto-Update zuerst zurueckrollen, dann erst aufgeben. + if [ "$FORCE_UPDATE" -eq 1 ] || [ "$UPDATE_ONLY" -eq 1 ]; then + log "Konfiguration ungültig — Rollback auf die letzte Sicherung." + rollback_conf || true + "$TG" --config /etc/telegraf/telegraf.conf --config-directory /etc/telegraf/telegraf.d --test --input-filter cpu:mem >/dev/null 2>&1 \ + || die "Konfiguration auch nach Rollback ungültig — telegraf --test prüfen." + log "Rollback erfolgreich, alte Konfiguration aktiv." + else + die "Konfiguration ungültig — telegraf --test prüfen." + fi +fi # -------------------------------------------------------------------------- # Dienst @@ -355,10 +468,37 @@ EOF log "Proxmox: systemd-Drop-in gesetzt — Dienst laeuft als root (pvesh braucht root)." fi +CHANGED=1 +if [ "$UPDATE_ONLY" -eq 1 ] && [ -n "$SNAPSHOT_BEFORE" ]; then + SNAPSHOT_AFTER="$(mktemp)" + cat /etc/telegraf/telegraf.d/*.conf /etc/telegraf/telegraf.conf 2>/dev/null > "$SNAPSHOT_AFTER" || true + for s in journal-tail syslog-tail node-info proxmox-ve gpu-rocm; do + [ -f "/etc/telegraf/$s.sh" ] && cat "/etc/telegraf/$s.sh" >> "$SNAPSHOT_AFTER" 2>/dev/null + done + if cmp -s "$SNAPSHOT_BEFORE" "$SNAPSHOT_AFTER"; then CHANGED=0; fi + rm -f "$SNAPSHOT_BEFORE" "$SNAPSHOT_AFTER" + if [ "$CHANGED" -eq 0 ]; then + log "Update-Only: keine Aenderung an Confs/Scripts — kein Neustart noetig." + # Versionsmarker TROTZDEM auf den Repo-Stand ziehen: sonst meldet der + # naechste Timer-Lauf erneut ein Update und laeuft endlos im Kreis. + _RV="$(curl -fsS -m 15 "$REPO_RAW/VERSION" 2>/dev/null | tr -d ' \r\n' || true)" + [ -n "$_RV" ] && printf '%s\n' "$_RV" > /etc/telegraf/CONFIG_VERSION + _RS="$(curl -fsS -m 20 "$REPO_RAW/install.sh" 2>/dev/null | { command -v sha256sum >/dev/null && sha256sum || shasum -a 256; } | cut -d' ' -f1 || true)" + [ -n "$_RS" ] && printf '%s\n' "$_RS" > /etc/telegraf/INSTALLER_SHA + printf '%s\n' "$REPO_RAW" > /etc/telegraf/REPO_RAW + exit 0 + fi + log "Update-Only: Aenderungen erkannt — Dienst wird neu gestartet." +fi + if command -v systemctl >/dev/null && [ -d /run/systemd/system ]; then systemctl daemon-reload - systemctl enable --now telegraf >/dev/null - systemctl restart telegraf + if [ "$UPDATE_ONLY" -eq 1 ]; then + systemctl restart telegraf + else + systemctl enable --now telegraf >/dev/null + systemctl restart telegraf + fi sleep 3 if ! systemctl is-active --quiet telegraf; then journalctl -u telegraf -n 20 --no-pager @@ -385,6 +525,159 @@ fi PROM_BASE="$(printf '%s' "$PROM_URL" | sed -E 's#/api/v1/write/?$##')" [ "$GPU" != "none" ] && log "GPU=$GPU erfasst. Hinweis: im Docker-Betrieb muss der GPU-Treiber im Container verfuegbar sein (nvidia-container-toolkit bzw. /dev/dri-Mount); im systemd-Betrieb ist das automatisch der Fall." +# -------------------------------------------------------------------------- +# Versionsmarker fuer den Auto-Updater +# -------------------------------------------------------------------------- +REMOTE_V="$(curl -fsS -m 15 "$REPO_RAW/VERSION" 2>/dev/null | tr -d ' \r\n' || true)" +printf '%s\n' "${REMOTE_V:-unbekannt}" > /etc/telegraf/CONFIG_VERSION +# Aktive Repo-Quelle festhalten, damit der Auto-Updater denselben Weg nutzt. +printf '%s\n' "$REPO_RAW" > /etc/telegraf/REPO_RAW +# Hash der Installer-Logik: erkennt auch Aenderungen ohne Versionssprung +# (z.B. eine Korrektur an journal-tail.sh). +if curl -fsS -m 20 "$REPO_RAW/install.sh" -o /tmp/.tg-installer.sha 2>/dev/null; then + if command -v sha256sum >/dev/null; then sha256sum /tmp/.tg-installer.sha | cut -d' ' -f1 > /etc/telegraf/INSTALLER_SHA + elif command -v shasum >/dev/null; then shasum -a 256 /tmp/.tg-installer.sha | cut -d' ' -f1 > /etc/telegraf/INSTALLER_SHA + fi + rm -f /tmp/.tg-installer.sha +fi +chmod 0644 /etc/telegraf/CONFIG_VERSION /etc/telegraf/INSTALLER_SHA 2>/dev/null || true + +# -------------------------------------------------------------------------- +# Auto-Updater-Timer +# -------------------------------------------------------------------------- +install_update_timer() { + IV="${1:-daily}" + case "$IV" in + daily) ONCAL="*-*-* 04:30:00" ;; + hourly) ONCAL="*-*-* *:30:00" ;; + weekly) ONCAL="Mon *-*-* 04:30:00" ;; + *min) ONCAL="" ;; # OnUnitActiveSec statt OnCalendar + *) ONCAL="*-*-* 04:30:00" ;; + esac + # Der Updater holt sich das Script frisch und ruft sich selbst mit + # --update-only auf. Token kommt aus /etc/default/telegraf (nicht im Repo). + cat > /usr/local/bin/telegraf-installer-update <<'UPD' +#!/bin/sh +# Auto-Updater: nur bei echter Aenderung etwas tun. +set -u +# Repo-Quelle: aus der Umgebung, sonst aus der beim Install hinterlegten +# Datei, sonst Default. So funktioniert der Updater auch mit Mirror/Testserver. +REPO_RAW="${REPO_RAW:-$(cat /etc/telegraf/REPO_RAW 2>/dev/null || echo https://gitea.m-m.bio/mm/netbird-telegraf-installer/raw/branch/main)}" +LOG="/var/log/telegraf-installer-update.log" +say() { printf '%s %s\n' "$(date -Is)" "$*" >> "$LOG"; } + +LOCAL_V="$(cat /etc/telegraf/CONFIG_VERSION 2>/dev/null || echo '')" +REMOTE_V="$(curl -fsS -m 20 "$REPO_RAW/VERSION" 2>/dev/null | tr -d ' \r\n' || true)" +[ -n "$REMOTE_V" ] || { say "Repo nicht erreichbar (NetBird down?) — kein Update."; exit 0; } + +NEED=0 +[ "$LOCAL_V" != "$REMOTE_V" ] && NEED=1 + +# Hash-Vergleich: erkennt Script-Fixes ohne Versionssprung +if [ "$NEED" -eq 0 ] && command -v sha256sum >/dev/null; then + TMP="$(mktemp)"; curl -fsS -m 25 "$REPO_RAW/install.sh" -o "$TMP" 2>/dev/null || true + if [ -s "$TMP" ]; then + R_SHA="$(sha256sum "$TMP" | cut -d' ' -f1)" + L_SHA="$(cat /etc/telegraf/INSTALLER_SHA 2>/dev/null || echo '')" + [ "$R_SHA" != "$L_SHA" ] && NEED=1 + fi + rm -f "$TMP" +fi + +if [ "$NEED" -eq 0 ]; then + say "aktuell ($LOCAL_V) — nichts zu tun." + exit 0 +fi + +say "Update $LOCAL_V -> $REMOTE_V" +TMPI="$(mktemp)" +if ! curl -fsS -m 60 "$REPO_RAW/install.sh" -o "$TMPI" 2>/dev/null; then + say "Download fehlgeschlagen."; rm -f "$TMPI"; exit 1 +fi +# --update-only: nur Confs/Scripts, kein Paket, kein Tokenwechsel. +# WICHTIG: REPO_RAW und die Node-Identitaet muessen mitgegeben werden, sonst +# faellt NODE_NAME auf den Hostnamen der AUFRUFENDEN Maschine zurueck und der +# Unterlauf holt die Version von der falschen Quelle. +UPD_NAME="$(sed -n 's/^NODE_NAME=//p' /etc/default/telegraf 2>/dev/null | head -1)" +UPD_ROLE="$(sed -n 's/^ROLE=//p' /etc/default/telegraf 2>/dev/null | head -1)" +UPD_TOKEN="$(sed -n 's/^TELEGRAF_TOKEN=//p' /etc/default/telegraf 2>/dev/null | head -1)" +UPD_COLL="$(sed -n 's/^COLLECTOR=//p' /etc/default/telegraf 2>/dev/null | head -1)" +[ -n "$UPD_NAME" ] || UPD_NAME="$(hostname -s)" +set -- --update-only --name "$UPD_NAME" --token "$UPD_TOKEN" +[ -n "$UPD_ROLE" ] && set -- "$@" --role "$UPD_ROLE" +[ -n "$UPD_COLL" ] && set -- "$@" --collector "$UPD_COLL" +if REPO_RAW="$REPO_RAW" sh "$TMPI" "$@" >> "$LOG" 2>&1; then + say "Update erfolgreich." +else + say "Update FEHLGESCHLAGEN — siehe oben. Alte Konfiguration bleibt aktiv." +fi +rm -f "$TMPI" +UPD + chmod 0755 /usr/local/bin/telegraf-installer-update + + if [ -d /etc/systemd/system ]; then + cat > /etc/systemd/system/telegraf-installer-update.service <<'EOF' +[Unit] +Description=Telegraf-Installer Auto-Update (nur bei Aenderung) +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/usr/local/bin/telegraf-installer-update +EOF + if [ -n "$ONCAL" ]; then + cat > /etc/systemd/system/telegraf-installer-update.timer < /etc/systemd/system/telegraf-installer-update.timer </dev/null 2>&1 \ + && log "Auto-Updater aktiv ($IV) — Log: /var/log/telegraf-installer-update.log" \ + || log "WARNUNG: Timer konnte nicht aktiviert werden (systemd nicht aktiv?)." + else + log "HINWEIS: kein systemd — Auto-Updater nur manuell (telegraf-installer-update)." + fi +} + +remove_update_timer() { + command -v systemctl >/dev/null 2>&1 || { log "Auto-Updater: systemctl fehlt — Dateien werden entfernt."; rm -f /etc/systemd/system/telegraf-installer-update.timer /etc/systemd/system/telegraf-installer-update.service /usr/local/bin/telegraf-installer-update; return 0; } + systemctl disable --now telegraf-installer-update.timer >/dev/null 2>&1 || true + rm -f /etc/systemd/system/telegraf-installer-update.timer \ + /etc/systemd/system/telegraf-installer-update.service \ + /usr/local/bin/telegraf-installer-update + systemctl daemon-reload 2>/dev/null || true + log "Auto-Updater entfernt." +} + +if [ "$REMOVE_TIMER" -eq 1 ]; then + if command -v systemctl >/dev/null 2>&1; then remove_update_timer + else log "Auto-Updater: kein systemd — nichts zu entfernen."; fi +fi +if [ -n "$TIMER_INTERVAL" ]; then install_update_timer "$TIMER_INTERVAL"; fi + log "OK — Node '$NODE_NAME' liefert an $PROM_URL (Metriken) und $LOKI_URL (Logs)." log "Prüfen: curl -s -H 'Authorization: Bearer ' '$PROM_BASE/api/v1/query?query=system_uptime{node=\"$NODE_NAME\"}'" log "Grafana: http://100.83.134.46:3000 (nur im NetBird)"