Add Ollama model auto-updater with systemd timer
ollama pull compares digests server-side so no download happens if a model is already current. Timer runs monthly offset 2h from kiwix. install.sh updated to handle all units generically. https://claude.ai/code/session_012gDnantBmFTWZGCiKyjazx
This commit is contained in:
Executable
+67
@@ -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"
|
||||||
+21
-7
@@ -1,19 +1,33 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Install kiwix-update systemd user units and enable the timer
|
# Install all local-ai systemd user units and enable timers
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
UNIT_DIR="$HOME/.config/systemd/user"
|
UNIT_DIR="$HOME/.config/systemd/user"
|
||||||
SRC="$(cd "$(dirname "$0")" && pwd)"
|
SRC="$(cd "$(dirname "$0")" && pwd)"
|
||||||
|
|
||||||
mkdir -p "$UNIT_DIR"
|
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 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 ""
|
echo ""
|
||||||
systemctl --user list-timers kiwix-update.timer
|
systemctl --user list-timers kiwix-update.timer ollama-update.timer
|
||||||
echo ""
|
echo ""
|
||||||
echo "Run manually anytime: systemctl --user start kiwix-update.service"
|
echo "Run manually:"
|
||||||
echo "Logs: journalctl --user -u kiwix-update.service"
|
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"
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
Reference in New Issue
Block a user