diff --git a/ollama_update.sh b/ollama_update.sh new file mode 100755 index 0000000..3173f92 --- /dev/null +++ b/ollama_update.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# ============================================================================= +# Ollama Model Auto-Updater +# Pulls latest version of every installed model. Ollama compares digests +# server-side — no download happens if the model is already current. +# Safe to run as a systemd timer. +# ============================================================================= + +OLLAMA_URL="${OLLAMA_HOST:-http://localhost:11434}" +LOG="$HOME/docker/ai-stack/logs/ollama-update.log" +mkdir -p "$(dirname "$LOG")" + +G='\033[0;32m'; Y='\033[1;33m'; C='\033[0;36m'; R='\033[0;31m'; N='\033[0m' +ok() { echo -e "${G}[OK]${N} $1" | tee -a "$LOG"; } +inf() { echo -e "${C}[..]${N} $1" | tee -a "$LOG"; } +wrn() { echo -e "${Y}[!!]${N} $1" | tee -a "$LOG"; } +err() { echo -e "${R}[XX]${N} $1" | tee -a "$LOG"; } + +echo "" | tee -a "$LOG" +echo "=== Ollama Model Update: $(date) ===" | tee -a "$LOG" +echo "" | tee -a "$LOG" + +# Check Ollama is reachable +if ! curl -sf "$OLLAMA_URL/api/tags" > /dev/null; then + err "Ollama not reachable at $OLLAMA_URL — is the container running?" + exit 1 +fi + +# Get installed model names from the API +mapfile -t MODELS < <( + curl -sf "$OLLAMA_URL/api/tags" | \ + grep -oP '"name"\s*:\s*"\K[^"]+' | \ + sort -u +) + +if [[ ${#MODELS[@]} -eq 0 ]]; then + wrn "No models found — nothing to update" + exit 0 +fi + +inf "Found ${#MODELS[@]} model(s): ${MODELS[*]}" +echo "" | tee -a "$LOG" + +UPDATED=0 +FAILED=0 + +for model in "${MODELS[@]}"; do + inf "Pulling $model..." + output=$(ollama pull "$model" 2>&1) + exit_code=$? + + if [[ $exit_code -ne 0 ]]; then + err "$model: pull failed" + echo "$output" >> "$LOG" + FAILED=$((FAILED + 1)) + elif echo "$output" | grep -q "up to date"; then + ok "$model: already up to date" + else + ok "$model: updated" + UPDATED=$((UPDATED + 1)) + fi +done + +echo "" | tee -a "$LOG" +inf "Done — $UPDATED updated, $FAILED failed" +echo "=== Complete: $(date) ===" | tee -a "$LOG" +echo "" | tee -a "$LOG" diff --git a/systemd/install.sh b/systemd/install.sh index ef27985..4f8c2bd 100755 --- a/systemd/install.sh +++ b/systemd/install.sh @@ -1,19 +1,33 @@ #!/bin/bash -# Install kiwix-update systemd user units and enable the timer +# Install all local-ai systemd user units and enable timers set -e UNIT_DIR="$HOME/.config/systemd/user" SRC="$(cd "$(dirname "$0")" && pwd)" mkdir -p "$UNIT_DIR" -ln -sf "$SRC/kiwix-update.service" "$UNIT_DIR/kiwix-update.service" -ln -sf "$SRC/kiwix-update.timer" "$UNIT_DIR/kiwix-update.timer" + +for unit in "$SRC"/*.service "$SRC"/*.timer; do + name=$(basename "$unit") + ln -sf "$unit" "$UNIT_DIR/$name" + echo "Linked $name" +done systemctl --user daemon-reload -systemctl --user enable --now kiwix-update.timer + +for timer in "$SRC"/*.timer; do + name=$(basename "$timer") + systemctl --user enable --now "$name" + echo "Enabled $name" +done echo "" -systemctl --user list-timers kiwix-update.timer +systemctl --user list-timers kiwix-update.timer ollama-update.timer echo "" -echo "Run manually anytime: systemctl --user start kiwix-update.service" -echo "Logs: journalctl --user -u kiwix-update.service" +echo "Run manually:" +echo " systemctl --user start kiwix-update.service" +echo " systemctl --user start ollama-update.service" +echo "" +echo "Logs:" +echo " journalctl --user -u kiwix-update.service -f" +echo " journalctl --user -u ollama-update.service -f" diff --git a/systemd/ollama-update.service b/systemd/ollama-update.service new file mode 100644 index 0000000..25a976b --- /dev/null +++ b/systemd/ollama-update.service @@ -0,0 +1,10 @@ +[Unit] +Description=Ollama model auto-updater +After=network-online.target +Wants=network-online.target + +[Service] +Type=oneshot +ExecStart=/bin/bash %h/local-ai/ollama_update.sh +StandardOutput=journal +StandardError=journal diff --git a/systemd/ollama-update.timer b/systemd/ollama-update.timer new file mode 100644 index 0000000..9051082 --- /dev/null +++ b/systemd/ollama-update.timer @@ -0,0 +1,11 @@ +[Unit] +Description=Monthly Ollama model update check +Requires=ollama-update.service + +[Timer] +OnCalendar=monthly +RandomizedDelaySec=2h +Persistent=true + +[Install] +WantedBy=timers.target