#!/usr/bin/env bash # Aktualisiert den Vulkan-llama.cpp-Build (ggml-org) auf den neuesten Release. # Wird vom MC2-„Engine Update"-Button via `sudo bash …` als ROOT aufgerufen (kein internes sudo). # # Wichtig: llama-swap wird VOR dem Datei-Austausch gestoppt — sonst ist die laufende llama-server- # Binary „Text file busy" und die mmap'ten .so-Libs dürfen nicht unter dem laufenden Prozess # getauscht werden. Danach Stack-Check (echte Inferenz); bei Fehler Auto-Rollback. # # Exit 0 = neuer Build verifiziert · 1 = fehlgeschlagen, Rollback ok (alter Build läuft) # · 2 = Update UND Rollback fehlgeschlagen (Stack evtl. kaputt — bitte prüfen) set -uo pipefail # bewusst KEIN -e: bei Fehlern kontrolliert zurückrollen statt hart abbrechen VULKAN_DIR=/opt/llamacpp-vulkan BAK_DIR=/opt/llamacpp-vulkan.bak # „letzter funktionierender Build" für Auto-Rollback SRC_DIR="$(cd "$(dirname "$0")" && pwd)" PIN_BUILD="${MC_ENGINE_BUILD:-}" # leer = neuester Release die(){ echo "$1" >&2; exit 1; } start_swap(){ systemctl start llama-swap || systemctl restart llama-swap; } # Inhalte von $1 nach $VULKAN_DIR spiegeln (Dir vorher leeren → sauberer Austausch). replace_dir(){ rm -rf "${VULKAN_DIR:?}" && mkdir -p "$VULKAN_DIR" || return 1 cp -a "$1/." "$VULKAN_DIR"/ || return 1 ln -sfn "$VULKAN_DIR/llama-server" /usr/local/bin/llama-server [ -x "$VULKAN_DIR/llama-server" ] } # 1. Release ermitteln + laden (vor jedem Eingriff am laufenden System) if [ -n "$PIN_BUILD" ]; then TAG="$PIN_BUILD" else TAG="$(curl -s https://api.github.com/repos/ggml-org/llama.cpp/releases/latest | jq -r .tag_name)" fi [ -n "$TAG" ] && [ "$TAG" != "null" ] || die "Konnte neuesten Release-Tag nicht ermitteln" ASSET="llama-${TAG}-bin-ubuntu-vulkan-x64.tar.gz" URL="https://github.com/ggml-org/llama.cpp/releases/download/${TAG}/${ASSET}" TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT echo "Lade Engine ${TAG} …" curl -fsSL -o "$TMP/v.tgz" "$URL" || die "Download fehlgeschlagen" tar xzf "$TMP/v.tgz" -C "$TMP" || die "Entpacken fehlgeschlagen" NEWDIR="$(echo "$TMP"/llama-*/)" # Tarball entpackt nach llama-/ [ -x "${NEWDIR}llama-server" ] || die "llama-server im Archiv nicht gefunden (${NEWDIR})" # 2. Aktuellen (funktionierenden) Build sichern → Auto-Rollback echo "Sichere aktuellen Build → ${BAK_DIR}" rm -rf "$BAK_DIR" cp -a "$VULKAN_DIR" "$BAK_DIR" || die "Backup fehlgeschlagen" # 3. llama-swap stoppen (gibt Binary/Libs frei), austauschen, wieder starten echo "Stoppe llama-swap für den Austausch…" systemctl stop llama-swap if replace_dir "${NEWDIR%/}"; then start_swap echo "Engine auf ${TAG} aktualisiert — verifiziere Stack…" if bash "$SRC_DIR/stack-postcheck.sh"; then echo "Engine-Update ${TAG} erfolgreich verifiziert." exit 0 fi echo "!! Stack-Check fehlgeschlagen — ROLLBACK auf vorherigen Build." else echo "!! Datei-Austausch fehlgeschlagen — ROLLBACK auf vorherigen Build." fi # 4. Auto-Rollback auf den gesicherten Build systemctl stop llama-swap if replace_dir "$BAK_DIR"; then start_swap if bash "$SRC_DIR/stack-postcheck.sh"; then echo "Rollback erfolgreich: vorheriger Build läuft wieder. (Update ${TAG} NICHT angewendet.)" exit 1 fi fi echo "!!! Rollback fehlgeschlagen — Stack möglicherweise kaputt! Backup liegt unter ${BAK_DIR}." exit 2