#!/bin/bash # shellcheck shell=bash # updateOllama: Lädt und installiert die aktuelle Ollama-Version (stable oder beta). set -euo pipefail shopt -s nullglob readonly GITHUB_API="https://api.github.com/repos/ollama/ollama" readonly INSTALL_URL="https://ollama.com/install.sh" PROG_NAME=$(basename "$0") || { printf 'Fehler: basename fehlgeschlagen\n' >&2; exit 1; } readonly PROG_NAME usage() { printf 'Verwendung: %s [--beta|-b]\n' "$PROG_NAME" >&2 exit 2 } check_dependencies() { local cmd for cmd in curl grep sed sort mktemp chmod; do if ! command -v "$cmd" >/dev/null 2>&1; then die "Benötigtes Kommando '$cmd' nicht gefunden." fi done } die() { printf 'Fehler: %s\n' "$1" >&2 exit "${2:-1}" } parse_args() { local use_beta=false while [[ $# -gt 0 ]]; do case "$1" in --beta|-b) use_beta=true ;; -h|--help) usage ;; *) usage ;; esac shift done printf '%s\n' "$use_beta" } get_local_version() { local version_line if ! version_line=$(ollama --version 2>/dev/null); then return 0 fi printf '%s\n' "$version_line" | grep -oEm1 '[0-9]+\.[0-9]+\.[0-9]+[^[:space:]]*' || true } # Helfer: GitHub-API abrufen und sicherstellen, dass die Antwort nicht leer ist. fetch_github_json() { local url=$1 local response if ! response=$(curl -fsSL "$url"); then die "API-Anfrage fehlgeschlagen: $url" fi if [[ -z "$response" ]]; then die "API-Antwort war leer: $url" fi printf '%s\n' "$response" } get_latest_version() { local url=$1 local json json=$(fetch_github_json "$url") printf '%s\n' "$json" | sed -nE 's/.*"tag_name": *"v?([^"]+)".*/\1/p' | head -n1 } # Vergleicht zwei Versionsstrings (SemVer-ähnlich, Suffixe alphabetisch). # Gibt -1, 0 oder 1 aus. cmp_versions() { local a=${1#v} b=${2#v} local a_main=${a%%-*} b_main=${b%%-*} local a_parts b_parts local max_len i IFS=. read -r -a a_parts <<< "$a_main" IFS=. read -r -a b_parts <<< "$b_main" max_len=${#a_parts[@]} if (( ${#b_parts[@]} > max_len )); then max_len=${#b_parts[@]} fi for (( i=0; i bv )); then printf '%s\n' 1 return 0 fi done local a_suffix=${a#*-} b_suffix=${b#*-} [[ "$a_suffix" == "$a_main" ]] && a_suffix="" [[ "$b_suffix" == "$b_main" ]] && b_suffix="" if [[ -z "$a_suffix" && -z "$b_suffix" ]]; then printf '%s\n' 0 return 0 fi if [[ -z "$a_suffix" ]]; then printf '%s\n' 1 return 0 fi if [[ -z "$b_suffix" ]]; then printf '%s\n' -1 return 0 fi if [[ "$a_suffix" == "$b_suffix" ]]; then printf '%s\n' 0 return 0 fi if [[ "$(printf '%s\n' "$a_suffix" "$b_suffix" | sort -V | head -n1)" == "$a_suffix" ]]; then printf '%s\n' -1 else printf '%s\n' 1 fi } install_ollama() { local version=$1 local tmp_script tmp_script=$(mktemp "${TMPDIR:-/tmp}/ollama-install.XXXXXX") # Temporäre Datei beim Beenden oder Abbruch aufräumen. trap 'rm -f "$tmp_script"' EXIT printf 'Lade Installations-Skript herunter ...\n' curl -fsSL "$INSTALL_URL" -o "$tmp_script" || die "Herunterladen von $INSTALL_URL fehlgeschlagen." if [[ ! -s "$tmp_script" ]]; then die "Installations-Skript ist leer." fi if [[ -n "$version" ]]; then export OLLAMA_VERSION="$version" fi # Skript ausführbar machen und ausführen. chmod +x "$tmp_script" || die "Konnte Installations-Skript nicht ausführbar machen." "$tmp_script" || die "Installation von Ollama ist fehlgeschlagen." } main() { local use_beta=false local local_ver stable_ver beta_ver local target_ver="" use_beta=$(parse_args "$@") check_dependencies local_ver=$(get_local_version) # Nur benötigte API-Daten abrufen. stable_ver=$(get_latest_version "$GITHUB_API/releases/latest") if [[ -z "$stable_ver" ]]; then die "Ermittlung der aktuellen Stable-Version fehlgeschlagen." fi if [[ "$use_beta" == true ]]; then beta_ver=$(get_latest_version "$GITHUB_API/releases?per_page=1") if [[ -z "$beta_ver" ]]; then die "Ermittlung der aktuellen Beta-Version fehlgeschlagen." fi else beta_ver="$stable_ver" fi printf 'Lokal: %s\n' "${local_ver:-(nicht installiert)}" printf 'Stable: %s\n' "$stable_ver" if [[ "$use_beta" == true ]] && [[ "$(cmp_versions "$beta_ver" "$stable_ver")" == 1 ]]; then printf 'Beta: %s\n' "$beta_ver" else printf 'Beta: keine neuere Beta verfuegbar\n' fi if [[ -z "$local_ver" ]]; then # Keine lokale Installation. if [[ "$use_beta" == true ]] && [[ "$(cmp_versions "$beta_ver" "$stable_ver")" == 1 ]]; then target_ver="$beta_ver" printf 'Ollama ist nicht installiert. Installation der Beta %s.\n' "$target_ver" else target_ver="$stable_ver" printf 'Ollama ist nicht installiert. Installation der Stable %s.\n' "$target_ver" fi else # Lokale Installation vorhanden. if [[ "$use_beta" == true ]]; then if [[ "$(cmp_versions "$beta_ver" "$stable_ver")" == 1 ]] \ && [[ "$(cmp_versions "$beta_ver" "$local_ver")" == 1 ]]; then target_ver="$beta_ver" printf 'Beta-Update verfuegbar: %s -> %s\n' "$local_ver" "$target_ver" elif [[ "$(cmp_versions "$stable_ver" "$local_ver")" == 1 ]]; then target_ver="$stable_ver" printf 'Stable-Update verfuegbar: %s -> %s\n' "$local_ver" "$target_ver" else printf 'Kein Update erforderlich.\n' return 0 fi else if [[ "$(cmp_versions "$stable_ver" "$local_ver")" == 1 ]]; then target_ver="$stable_ver" printf 'Update verfuegbar: %s -> %s\n' "$local_ver" "$target_ver" else printf 'Kein Update erforderlich.\n' return 0 fi fi fi # Bei Beta-Installation die gewünschte Version an das Installer-Skript übergeben. if [[ "$use_beta" == true && -n "$target_ver" && "$target_ver" != "$stable_ver" ]]; then install_ollama "$target_ver" else install_ollama "" fi } main "$@"