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
+8
-3
@@ -1,8 +1,10 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# NetMover auf Debian 13 installieren bzw. aktualisieren (als root ausführen).
|
# NetMover auf Debian 13 installieren bzw. aktualisieren (als root ausführen).
|
||||||
#
|
#
|
||||||
# ./deploy/install.sh # aus diesem Verzeichnis installieren
|
# git clone https://git.wilde-server.de/florian.wilde/netmover.git /opt/netmover/src
|
||||||
# ./deploy/install.sh 'git+https://git.wilde-server.de/florian.wilde/netmover.git@v0.1.0'
|
# /opt/netmover/src/deploy/install.sh
|
||||||
|
#
|
||||||
|
# Spätere Updates: netmover-update (siehe deploy/update.sh).
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
SOURCE="${1:-$(cd "$(dirname "$0")/.." && pwd)}"
|
SOURCE="${1:-$(cd "$(dirname "$0")/.." && pwd)}"
|
||||||
@@ -16,7 +18,7 @@ fi
|
|||||||
echo "==> Pakete"
|
echo "==> Pakete"
|
||||||
export DEBIAN_FRONTEND=noninteractive
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
apt-get update -qq
|
apt-get update -qq
|
||||||
apt-get install -y -qq python3 python3-venv cifs-utils nfs-common >/dev/null
|
apt-get install -y -qq python3 python3-venv cifs-utils nfs-common git >/dev/null
|
||||||
|
|
||||||
echo "==> Virtuelle Umgebung in $PREFIX/venv"
|
echo "==> Virtuelle Umgebung in $PREFIX/venv"
|
||||||
install -d -m 0755 "$PREFIX"
|
install -d -m 0755 "$PREFIX"
|
||||||
@@ -31,6 +33,9 @@ if [ ! -f /etc/netmover/netmover.env ]; then
|
|||||||
fi
|
fi
|
||||||
install -d -m 0755 /mnt/netmover
|
install -d -m 0755 /mnt/netmover
|
||||||
|
|
||||||
|
echo "==> Update-Skript"
|
||||||
|
install -m 0755 "$(dirname "$0")/update.sh" /usr/local/sbin/netmover-update
|
||||||
|
|
||||||
echo "==> systemd"
|
echo "==> systemd"
|
||||||
install -m 0644 "$(dirname "$0")/netmover.service" /etc/systemd/system/netmover.service
|
install -m 0644 "$(dirname "$0")/netmover.service" /etc/systemd/system/netmover.service
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
|
|||||||
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
|
||||||
@@ -33,6 +33,7 @@ dev = [
|
|||||||
"ruff>=0.6",
|
"ruff>=0.6",
|
||||||
"mypy>=1.11",
|
"mypy>=1.11",
|
||||||
"types-paramiko",
|
"types-paramiko",
|
||||||
|
"shellcheck-py",
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|||||||
Reference in New Issue
Block a user