diff --git a/update-iventoy.sh b/update-iventoy.sh index ffc4ed0..2ec8597 100644 --- a/update-iventoy.sh +++ b/update-iventoy.sh @@ -1,6 +1,10 @@ #!/bin/bash set -euo pipefail +# ================================================== +# Konfiguration +# ================================================== + BASE="/opt" CURRENT="/opt/iventoy" @@ -14,39 +18,44 @@ SERVICE="iventoy" TMP="/tmp/iventoy-update" GITHUB_REPO="ventoy/PXE" -MAX_BACKUPS=10 +MAX_CONFIG_BACKUPS=10 +KEEP_VERSIONS=3 + +# ================================================== +# Ausgabe +# ================================================== echo "==========================================" echo " iVentoy Update" echo "==========================================" echo -# -------------------------------------------------- -# Root check -# -------------------------------------------------- +# ================================================== +# Root Check +# ================================================== if [ "$(id -u)" -ne 0 ]; then echo "ERROR: Dieses Script muss als root laufen." exit 1 fi -# -------------------------------------------------- -# Dependencies -# -------------------------------------------------- +# ================================================== +# Abhängigkeiten +# ================================================== apt-get update -qq -apt-get install -y -qq curl tar >/dev/null +apt-get install -y -qq curl tar iproute2 >/dev/null -# -------------------------------------------------- -# Persistent directories -# -------------------------------------------------- +# ================================================== +# Persistente Verzeichnisse +# ================================================== mkdir -p "$ISO_DIR" mkdir -p "$CONFIG_DIR" -# -------------------------------------------------- -# Latest Version ermitteln -# -------------------------------------------------- +# ================================================== +# Aktuelle Version online ermitteln +# ================================================== echo "Ermittle aktuelle iVentoy-Version..." @@ -69,14 +78,16 @@ TARGET="${BASE}/iventoy-${VERSION}" echo "Neueste Version: $VERSION" -# -------------------------------------------------- -# Prüfen ob bereits aktuell -# -------------------------------------------------- +# ================================================== +# Bereits aktuell? +# ================================================== if [ -L "$CURRENT" ]; then + CURRENT_TARGET=$(readlink -f "$CURRENT" || true) if [ "$CURRENT_TARGET" = "$TARGET" ]; then + echo echo "==========================================" echo " iVentoy ist bereits aktuell" @@ -85,30 +96,35 @@ if [ -L "$CURRENT" ]; then echo "Aktive Version: $VERSION" echo "Installation: $CURRENT -> $TARGET" echo + exit 0 fi fi -# -------------------------------------------------- -# Bestehende Config übernehmen -# -------------------------------------------------- +# ================================================== +# Bestehende Config erstmalig übernehmen +# ================================================== if [ ! -f "$CONFIG_FILE" ]; then if [ -f "${CURRENT}/data/config.dat" ]; then + echo echo "Übernehme bestehende iVentoy Config..." + cp -a "${CURRENT}/data/config.dat" "$CONFIG_FILE" + else + echo echo "WARNUNG: Keine bestehende config.dat gefunden." - fi + fi fi -# -------------------------------------------------- +# ================================================== # Config Backup -# -------------------------------------------------- +# ================================================== if [ -f "$CONFIG_FILE" ]; then @@ -120,11 +136,11 @@ if [ -f "$CONFIG_FILE" ]; then cp -a "$CONFIG_FILE" "$BACKUP" - # -------------------------------------------------- + # ---------------------------------------------- # Backup Rotation - # -------------------------------------------------- + # ---------------------------------------------- - echo "Behalte maximal ${MAX_BACKUPS} Config-Backups..." + echo "Behalte maximal ${MAX_CONFIG_BACKUPS} Config-Backups..." find "$CONFIG_DIR" \ -maxdepth 1 \ @@ -132,14 +148,14 @@ if [ -f "$CONFIG_FILE" ]; then -name 'config.dat.bak-*' \ -printf '%T@ %p\n' \ | sort -nr \ - | tail -n +"$((MAX_BACKUPS + 1))" \ + | tail -n +"$((MAX_CONFIG_BACKUPS + 1))" \ | cut -d' ' -f2- \ | xargs -r rm -f fi -# -------------------------------------------------- +# ================================================== # Download / Entpacken -# -------------------------------------------------- +# ================================================== if [ -d "$TARGET" ]; then @@ -169,18 +185,19 @@ else EXTRACTED="${TMP}/iventoy-${VERSION}" if [ ! -d "$EXTRACTED" ]; then + echo "ERROR: Erwartetes Verzeichnis wurde nicht gefunden:" echo " $EXTRACTED" + exit 1 fi mv "$EXTRACTED" "$TARGET" - fi -# -------------------------------------------------- +# ================================================== # ISO Symlink -# -------------------------------------------------- +# ================================================== echo echo "Setze ISO-Symlink..." @@ -188,22 +205,24 @@ echo "Setze ISO-Symlink..." rm -rf "${TARGET}/iso" ln -s "$ISO_DIR" "${TARGET}/iso" -# -------------------------------------------------- +# ================================================== # Config Symlink -# -------------------------------------------------- +# ================================================== if [ -f "$CONFIG_FILE" ]; then echo "Setze Config-Symlink..." rm -f "${TARGET}/data/config.dat" - ln -s "$CONFIG_FILE" "${TARGET}/data/config.dat" + ln -s \ + "$CONFIG_FILE" \ + "${TARGET}/data/config.dat" fi -# -------------------------------------------------- -# Service stoppen -# -------------------------------------------------- +# ================================================== +# iVentoy stoppen +# ================================================== echo echo "Stoppe iVentoy..." @@ -212,9 +231,13 @@ systemctl stop "$SERVICE" 2>/dev/null || true sleep 2 -# -------------------------------------------------- -# Alte direkte Installation sichern -# -------------------------------------------------- +# ================================================== +# Alte direkte Installation migrieren +# ================================================== +# +# Falls /opt/iventoy beim ersten Lauf noch ein +# echtes Verzeichnis statt eines Symlinks ist. +# if [ -e "$CURRENT" ] && [ ! -L "$CURRENT" ]; then @@ -225,12 +248,11 @@ if [ -e "$CURRENT" ] && [ ! -L "$CURRENT" ]; then echo " $CURRENT -> $OLD" mv "$CURRENT" "$OLD" - fi -# -------------------------------------------------- -# Current Symlink atomar setzen -# -------------------------------------------------- +# ================================================== +# Current Symlink atomar umschalten +# ================================================== echo echo "Aktiviere iVentoy $VERSION..." @@ -238,53 +260,133 @@ echo "Aktiviere iVentoy $VERSION..." ln -sfn "$TARGET" "${CURRENT}.new" mv -Tf "${CURRENT}.new" "$CURRENT" -# -------------------------------------------------- +# ================================================== # Service starten -# -------------------------------------------------- +# ================================================== echo echo "Starte iVentoy..." systemctl start "$SERVICE" -sleep 3 +sleep 4 -# -------------------------------------------------- -# Health Check -# -------------------------------------------------- +# ================================================== +# Healthcheck +# ================================================== + +echo +echo "Führe Healthcheck aus..." FAILED=0 -if ! systemctl is-active --quiet "$SERVICE"; then - echo "ERROR: systemd Service läuft nicht." +# Service +if systemctl is-active --quiet "$SERVICE"; then + echo "OK: iVentoy systemd service is active" +else + echo "ERROR: iVentoy systemd service is NOT active" FAILED=1 fi -if ! ss -lntH | awk '{print $4}' | grep -Eq '[:.]26000$'; then - echo "ERROR: TCP 26000 lauscht nicht." +# TCP 26000 +if ss -lntH | awk '{print $4}' | grep -Eq '[:.]26000$'; then + echo "OK: TCP 26000 is listening" +else + echo "ERROR: TCP 26000 is NOT listening" FAILED=1 fi -if ! ss -lntH | awk '{print $4}' | grep -Eq '[:.]16000$'; then - echo "ERROR: TCP 16000 lauscht nicht." +# TCP 16000 +if ss -lntH | awk '{print $4}' | grep -Eq '[:.]16000$'; then + echo "OK: TCP 16000 is listening" +else + echo "ERROR: TCP 16000 is NOT listening" FAILED=1 fi -if ! ss -lnuH | awk '{print $4}' | grep -Eq '[:.]69$'; then - echo "ERROR: UDP 69 lauscht nicht." +# UDP 69 +if ss -lnuH | awk '{print $4}' | grep -Eq '[:.]69$'; then + echo "OK: UDP 69 is listening" +else + echo "ERROR: UDP 69 is NOT listening" FAILED=1 fi -if ! ss -lnuH | awk '{print $4}' | grep -Eq '[:.]4011$'; then - echo "ERROR: UDP 4011 lauscht nicht." +# UDP 4011 +if ss -lnuH | awk '{print $4}' | grep -Eq '[:.]4011$'; then + echo "OK: UDP 4011 is listening" +else + echo "ERROR: UDP 4011 is NOT listening" FAILED=1 fi -if ! ss -lnuH | awk '{print $4}' | grep -Eq '[:.]67$'; then - echo "ERROR: UDP 67 lauscht nicht." +# UDP 67 +if ss -lnuH | awk '{print $4}' | grep -Eq '[:.]67$'; then + echo "OK: UDP 67 is listening" +else + echo "ERROR: UDP 67 is NOT listening" FAILED=1 fi +# Web GUI +if curl -fsS \ + --max-time 5 \ + http://127.0.0.1:26000/ \ + >/dev/null 2>&1; then + + echo "OK: Web GUI responds" + +else + + echo "ERROR: Web GUI does NOT respond" + FAILED=1 + +fi + +# PXE HTTP Bind-IP bestimmen +PXE_BIND=$(ss -lntH | awk '$4 ~ /:16000$/ {print $4; exit}') + +if [ -n "$PXE_BIND" ]; then + + PXE_IP="${PXE_BIND%:16000}" + + PXE_IP="${PXE_IP#[}" + PXE_IP="${PXE_IP%]}" + + if [[ "$PXE_IP" == "*" || \ + "$PXE_IP" == "0.0.0.0" || \ + "$PXE_IP" == "::" ]]; then + + PXE_IP="127.0.0.1" + + fi + + if curl -sS \ + --max-time 5 \ + -o /dev/null \ + "http://${PXE_IP}:16000/" \ + >/dev/null 2>&1; then + + echo "OK: PXE HTTP service on ${PXE_IP}:16000 responds" + + else + + echo "ERROR: PXE HTTP service on ${PXE_IP}:16000 does NOT respond" + FAILED=1 + + fi + +else + + echo "ERROR: Could not determine PXE HTTP bind address" + FAILED=1 + +fi + +# ================================================== +# Healthcheck fehlgeschlagen +# ================================================== + if [ "$FAILED" -ne 0 ]; then echo @@ -294,19 +396,73 @@ if [ "$FAILED" -ne 0 ]; then echo if [ -f "${CURRENT}/log/log.txt" ]; then + echo "Letzte iVentoy Log-Einträge:" - tail -n 40 "${CURRENT}/log/log.txt" || true + echo + + tail -n 50 "${CURRENT}/log/log.txt" || true + fi + echo + echo "Alte iVentoy-Versionen wurden NICHT gelöscht." + echo "Damit ist ein manueller Rollback weiterhin möglich." + exit 1 fi -# -------------------------------------------------- -# Cleanup -# -------------------------------------------------- +# ================================================== +# Alte Versionen aufräumen +# ================================================== + +echo +echo "Räume alte iVentoy-Versionen auf..." +echo "Behalte maximal ${KEEP_VERSIONS} Versionen." + +ACTIVE_TARGET=$(readlink -f "$CURRENT") + +mapfile -t VERSION_DIRS < <( + find "$BASE" \ + -maxdepth 1 \ + -mindepth 1 \ + -type d \ + -name 'iventoy-[0-9]*' \ + -printf '%T@ %p\n' \ + | sort -nr \ + | cut -d' ' -f2- +) + +COUNT=0 + +for DIR in "${VERSION_DIRS[@]}"; do + + # Aktive Version niemals löschen + if [ "$(readlink -f "$DIR")" = "$ACTIVE_TARGET" ]; then + COUNT=$((COUNT + 1)) + continue + fi + + COUNT=$((COUNT + 1)) + + if [ "$COUNT" -gt "$KEEP_VERSIONS" ]; then + + echo "Lösche alte Version:" + echo " $DIR" + + rm -rf "$DIR" + fi +done + +# ================================================== +# Temp-Dateien aufräumen +# ================================================== rm -rf "$TMP" +# ================================================== +# Abschluss +# ================================================== + echo echo "==========================================" echo " Update erfolgreich" @@ -325,5 +481,8 @@ echo "ISO:" echo " ${CURRENT}/iso -> $ISO_DIR" echo echo "Config-Backups:" -echo " maximal $MAX_BACKUPS" +echo " maximal $MAX_CONFIG_BACKUPS" +echo +echo "Installierte iVentoy-Versionen:" +echo " maximal $KEEP_VERSIONS" echo \ No newline at end of file