feat(deploy): netmover-update mit Sicherung, Changelog-Auszug und Healthcheck
Installation als Git-Klon unter /opt/netmover/src; install.sh installiert git und das Update-Skript. Skripte mit shellcheck geprüft. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
fb975f1eae
commit
ce5bef8306
Executable
+151
@@ -0,0 +1,151 @@
|
||||
#!/bin/sh
|
||||
# NetMover aktualisieren (als root). Wird von install.sh als
|
||||
# /usr/local/sbin/netmover-update installiert.
|
||||
#
|
||||
# netmover-update # auf die neueste Version (neuester Tag vX.Y.Z)
|
||||
# netmover-update v0.2.0 # auf eine bestimmte Version (auch zurück)
|
||||
# netmover-update --list # verfügbare Versionen anzeigen
|
||||
#
|
||||
# Ablauf: Tags holen → Datenbank und Schlüssel sichern → Version auschecken →
|
||||
# install.sh (installiert, migriert beim Start, startet den Dienst neu) →
|
||||
# Gesundheit prüfen. Die Mounts bleiben dabei eingehängt.
|
||||
set -eu
|
||||
|
||||
SRC="${NETMOVER_SRC:-/opt/netmover/src}"
|
||||
VENV=/opt/netmover/venv
|
||||
ENV_FILE=/etc/netmover/netmover.env
|
||||
BACKUP_ROOT=/var/backups/netmover
|
||||
KEEP_BACKUPS=10
|
||||
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Bitte als root ausführen." >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -d "$SRC/.git" ]; then
|
||||
echo "Kein Git-Klon unter $SRC. Einmalig einrichten:" >&2
|
||||
echo " git clone https://git.wilde-server.de/florian.wilde/netmover.git $SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Einstellungen des Dienstes (Port, Datenverzeichnis)
|
||||
NETMOVER_PORT=8080
|
||||
NETMOVER_DATA_DIR=/var/lib/netmover
|
||||
# shellcheck disable=SC1090
|
||||
[ -f "$ENV_FILE" ] && . "$ENV_FILE"
|
||||
|
||||
cd "$SRC"
|
||||
git fetch --tags --quiet origin
|
||||
|
||||
if [ "${1:-}" = "--list" ]; then
|
||||
git tag -l 'v*' --sort=-v:refname
|
||||
exit 0
|
||||
fi
|
||||
|
||||
TARGET="${1:-$(git tag -l 'v*' --sort=-v:refname | head -n 1)}"
|
||||
if ! git rev-parse -q --verify "refs/tags/$TARGET" >/dev/null; then
|
||||
echo "Version $TARGET gibt es nicht. Verfügbar:" >&2
|
||||
git tag -l 'v*' --sort=-v:refname | head -n 10 >&2
|
||||
exit 1
|
||||
fi
|
||||
CURRENT="v$("$VENV/bin/netmover" version 2>/dev/null || echo "?")"
|
||||
echo "Installiert: $CURRENT"
|
||||
echo "Ziel: $TARGET"
|
||||
if [ "$CURRENT" = "$TARGET" ] && [ "${FORCE:-0}" != "1" ]; then
|
||||
echo "Bereits auf dem gewünschten Stand (FORCE=1 erzwingt eine Neuinstallation)."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
NEWEST="$(printf '%s\n%s\n' "$CURRENT" "$TARGET" | sort -V | tail -n 1)"
|
||||
if [ "$NEWEST" = "$CURRENT" ] && [ "$CURRENT" != "$TARGET" ]; then
|
||||
echo
|
||||
echo "!! Zurückstufen auf eine ältere Version: Wurde die Datenbank inzwischen migriert,"
|
||||
echo " startet die alte Version nicht. Dann vorher die Sicherung von *vor* dem Update"
|
||||
echo " zurückspielen (siehe $BACKUP_ROOT, Anleitung im README)."
|
||||
printf " Trotzdem fortfahren? [j/N] "
|
||||
read -r answer
|
||||
[ "$answer" = "j" ] || [ "$answer" = "J" ] || exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "==> Änderungen laut Changelog"
|
||||
git show "$TARGET:CHANGELOG.md" | awk -v cur="${CURRENT#v}" '
|
||||
/^## \[/ { if (index($0, "[" cur "]")) exit; show = ($0 !~ /Unreleased/) }
|
||||
show' | head -n 60
|
||||
|
||||
echo
|
||||
echo "==> Sicherung"
|
||||
STAMP="$(date +%Y%m%d-%H%M%S)"
|
||||
BACKUP="$BACKUP_ROOT/$STAMP-$CURRENT"
|
||||
install -d -m 0700 "$BACKUP_ROOT" "$BACKUP"
|
||||
# Konsistente Kopie auch bei laufendem Dienst (SQLite-Online-Backup)
|
||||
"$VENV/bin/python" - "$NETMOVER_DATA_DIR/netmover.db" "$BACKUP/netmover.db" <<'EOF'
|
||||
import sqlite3, sys
|
||||
src, dst = sqlite3.connect(sys.argv[1]), sqlite3.connect(sys.argv[2])
|
||||
with dst:
|
||||
src.backup(dst)
|
||||
src.close(); dst.close()
|
||||
EOF
|
||||
for f in secret.key session.key; do
|
||||
[ -f "$NETMOVER_DATA_DIR/$f" ] && cp -p "$NETMOVER_DATA_DIR/$f" "$BACKUP/"
|
||||
done
|
||||
[ -f "$ENV_FILE" ] && cp -p "$ENV_FILE" "$BACKUP/"
|
||||
chmod 0600 "$BACKUP"/*
|
||||
echo " $BACKUP"
|
||||
# alte Sicherungen aufräumen
|
||||
find "$BACKUP_ROOT" -mindepth 1 -maxdepth 1 -type d -print | sort \
|
||||
| head -n "-$KEEP_BACKUPS" | xargs -r rm -rf --
|
||||
|
||||
echo
|
||||
echo "==> Version $TARGET auschecken und installieren"
|
||||
git -c advice.detachedHead=false checkout --quiet "$TARGET"
|
||||
"$SRC/deploy/install.sh" "$SRC" >/tmp/netmover-update.log 2>&1 || {
|
||||
echo "install.sh ist fehlgeschlagen – Ausgabe: /tmp/netmover-update.log" >&2
|
||||
tail -n 20 /tmp/netmover-update.log >&2
|
||||
FAILED=1
|
||||
}
|
||||
|
||||
echo
|
||||
echo "==> Prüfung"
|
||||
OK=0
|
||||
if [ "${FAILED:-0}" != "1" ]; then
|
||||
i=0
|
||||
while [ $i -lt 30 ]; do
|
||||
if "$VENV/bin/python" - "$NETMOVER_PORT" <<'EOF'
|
||||
import json, sys, urllib.error, urllib.request
|
||||
url = f"http://127.0.0.1:{sys.argv[1]}/healthz"
|
||||
try:
|
||||
body = urllib.request.urlopen(url, timeout=3).read()
|
||||
except urllib.error.HTTPError as exc: # 503 = läuft, meldet aber Probleme
|
||||
body = exc.read()
|
||||
except OSError:
|
||||
sys.exit(1)
|
||||
data = json.loads(body)
|
||||
print(f" Gesundheit: {data['status']}")
|
||||
for p in data.get("problems", []):
|
||||
print(f" – {p}")
|
||||
EOF
|
||||
then
|
||||
OK=1
|
||||
break
|
||||
fi
|
||||
i=$((i + 1))
|
||||
sleep 1
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$OK" = "1" ] && systemctl is-active --quiet netmover; then
|
||||
echo " Dienst läuft: $("$VENV/bin/netmover" version)"
|
||||
echo
|
||||
echo "Fertig. Sicherung: $BACKUP"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "!! Der Dienst läuft nach dem Update nicht richtig." >&2
|
||||
echo " Log: journalctl -u netmover -n 50" >&2
|
||||
echo " Zurück auf $CURRENT (Datenbank aus der Sicherung, weil sie migriert sein kann):" >&2
|
||||
echo " systemctl stop netmover" >&2
|
||||
echo " cp $BACKUP/netmover.db $NETMOVER_DATA_DIR/netmover.db" >&2
|
||||
echo " rm -f $NETMOVER_DATA_DIR/netmover.db-wal $NETMOVER_DATA_DIR/netmover.db-shm" >&2
|
||||
echo " netmover-update $CURRENT" >&2
|
||||
exit 1
|
||||
Reference in New Issue
Block a user