243 lines
7.9 KiB
Bash
Executable File
243 lines
7.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
REPO_URL="https://github.com/TySP-Dev/ollama-ai-answers-searxng"
|
|
REPO_DIR="/tmp/ollama-ai-answers-searxng"
|
|
|
|
# ============================================================
|
|
echo "=== Step 1: Clone or update repo ==="
|
|
# ============================================================
|
|
if [ -d "$REPO_DIR/.git" ]; then
|
|
echo "Repository already exists — pulling latest changes..."
|
|
git -C "$REPO_DIR" pull
|
|
else
|
|
git clone "$REPO_URL" "$REPO_DIR"
|
|
fi
|
|
cd "$REPO_DIR"
|
|
|
|
# ============================================================
|
|
echo "=== Step 2: Build dist file ==="
|
|
# ============================================================
|
|
if ! python3 build.py; then
|
|
echo "ERROR: build.py failed"
|
|
exit 1
|
|
fi
|
|
|
|
# ============================================================
|
|
echo "=== Step 3: Detect SearXNG Docker Compose installation ==="
|
|
# ============================================================
|
|
CANDIDATES=(
|
|
"$HOME/searxng/docker-compose.yml"
|
|
"$HOME/docker/searxng/docker-compose.yml"
|
|
"/opt/searxng/docker-compose.yml"
|
|
"/etc/searxng/docker-compose.yml"
|
|
)
|
|
|
|
FOUND=()
|
|
for f in "${CANDIDATES[@]}"; do
|
|
if [ -f "$f" ] && grep -q "searxng" "$f" 2>/dev/null; then
|
|
FOUND+=("$f")
|
|
fi
|
|
done
|
|
|
|
# Also do a broader search
|
|
while IFS= read -r f; do
|
|
# Avoid duplicates
|
|
already=false
|
|
for existing in "${FOUND[@]}"; do
|
|
[ "$f" = "$existing" ] && already=true && break
|
|
done
|
|
$already || FOUND+=("$f")
|
|
done < <(find "$HOME" -maxdepth 6 -name "docker-compose.yml" -exec grep -l "searxng" {} \; 2>/dev/null)
|
|
|
|
if [ ${#FOUND[@]} -eq 0 ]; then
|
|
echo "ERROR: No docker-compose.yml containing 'searxng' was found."
|
|
echo "Please set COMPOSE_FILE manually and re-run."
|
|
exit 1
|
|
elif [ ${#FOUND[@]} -eq 1 ]; then
|
|
COMPOSE_FILE="${FOUND[0]}"
|
|
echo "Found: $COMPOSE_FILE"
|
|
else
|
|
echo "Multiple docker-compose.yml files found:"
|
|
for i in "${!FOUND[@]}"; do
|
|
echo " [$((i+1))] ${FOUND[$i]}"
|
|
done
|
|
read -rp "Select a file [1-${#FOUND[@]}]: " choice
|
|
idx=$((choice - 1))
|
|
if [ "$idx" -lt 0 ] || [ "$idx" -ge "${#FOUND[@]}" ]; then
|
|
echo "ERROR: Invalid selection"
|
|
exit 1
|
|
fi
|
|
COMPOSE_FILE="${FOUND[$idx]}"
|
|
fi
|
|
|
|
COMPOSE_DIR="$(dirname "$COMPOSE_FILE")"
|
|
echo "Using: $COMPOSE_FILE"
|
|
|
|
# ============================================================
|
|
echo "=== Step 4: Create plugins directory ==="
|
|
# ============================================================
|
|
PLUGINS_DIR="$COMPOSE_DIR/plugins"
|
|
mkdir -p "$PLUGINS_DIR"
|
|
echo "Plugins directory: $PLUGINS_DIR"
|
|
|
|
# ============================================================
|
|
echo "=== Step 5: Copy built plugin ==="
|
|
# ============================================================
|
|
cp dist/ollama_answers.py "$PLUGINS_DIR/ollama_answers.py"
|
|
echo "Plugin installed to $PLUGINS_DIR/ollama_answers.py"
|
|
|
|
# ============================================================
|
|
echo "=== Step 6: Update docker-compose.yml volume mount ==="
|
|
# ============================================================
|
|
python3 - "$COMPOSE_FILE" <<'PYEOF'
|
|
import re, sys
|
|
compose_file = sys.argv[1]
|
|
content = open(compose_file).read()
|
|
mount = ' - ./plugins/ollama_answers.py:/usr/local/searxng/searx/plugins/ollama_answers.py:Z'
|
|
if 'ollama_answers.py' not in content:
|
|
content = re.sub(
|
|
r'(volumes:(?:\n\s+- [^\n]+)*)',
|
|
lambda m: m.group(0) + '\n' + mount,
|
|
content, count=1
|
|
)
|
|
open(compose_file, 'w').write(content)
|
|
print('Added volume mount to docker-compose.yml')
|
|
else:
|
|
print('Volume mount already present')
|
|
PYEOF
|
|
|
|
# ============================================================
|
|
echo "=== Step 7: Find and update settings.yml ==="
|
|
# ============================================================
|
|
SETTINGS_CANDIDATES=(
|
|
"$COMPOSE_DIR/core-config/settings.yml"
|
|
"$COMPOSE_DIR/config/settings.yml"
|
|
"$COMPOSE_DIR/searxng/settings.yml"
|
|
)
|
|
|
|
SETTINGS_FOUND=()
|
|
for f in "${SETTINGS_CANDIDATES[@]}"; do
|
|
[ -f "$f" ] && SETTINGS_FOUND+=("$f")
|
|
done
|
|
|
|
# Broader search within COMPOSE_DIR
|
|
while IFS= read -r f; do
|
|
already=false
|
|
for existing in "${SETTINGS_FOUND[@]}"; do
|
|
[ "$f" = "$existing" ] && already=true && break
|
|
done
|
|
$already || SETTINGS_FOUND+=("$f")
|
|
done < <(find "$COMPOSE_DIR" -name "settings.yml" 2>/dev/null | head -5)
|
|
|
|
if [ ${#SETTINGS_FOUND[@]} -eq 0 ]; then
|
|
echo "WARNING: settings.yml not found. Add this manually:"
|
|
echo ""
|
|
echo " plugins:"
|
|
echo " searx.plugins.ollama_answers.SXNGPlugin:"
|
|
echo " active: true"
|
|
echo ""
|
|
SETTINGS_FILE=""
|
|
elif [ ${#SETTINGS_FOUND[@]} -eq 1 ]; then
|
|
SETTINGS_FILE="${SETTINGS_FOUND[0]}"
|
|
echo "Found: $SETTINGS_FILE"
|
|
else
|
|
echo "Multiple settings.yml files found:"
|
|
for i in "${!SETTINGS_FOUND[@]}"; do
|
|
echo " [$((i+1))] ${SETTINGS_FOUND[$i]}"
|
|
done
|
|
read -rp "Select a file [1-${#SETTINGS_FOUND[@]}]: " schoice
|
|
sidx=$((schoice - 1))
|
|
if [ "$sidx" -lt 0 ] || [ "$sidx" -ge "${#SETTINGS_FOUND[@]}" ]; then
|
|
echo "ERROR: Invalid selection"
|
|
exit 1
|
|
fi
|
|
SETTINGS_FILE="${SETTINGS_FOUND[$sidx]}"
|
|
fi
|
|
|
|
if [ -n "$SETTINGS_FILE" ]; then
|
|
python3 - "$SETTINGS_FILE" <<'PYEOF'
|
|
import sys
|
|
settings_file = sys.argv[1]
|
|
content = open(settings_file).read()
|
|
entry = 'searx.plugins.ollama_answers.SXNGPlugin:\n active: true'
|
|
if 'ollama_answers' not in content:
|
|
if 'plugins:' in content:
|
|
content = content.replace('plugins:', 'plugins:\n\n ' + entry, 1)
|
|
else:
|
|
content += '\nplugins:\n\n ' + entry + '\n'
|
|
open(settings_file, 'w').write(content)
|
|
print('Added plugin entry to settings.yml')
|
|
else:
|
|
print('Plugin entry already present')
|
|
PYEOF
|
|
fi
|
|
|
|
# ============================================================
|
|
echo "=== Step 8: Configure environment variables ==="
|
|
# ============================================================
|
|
python3 - "$COMPOSE_FILE" <<'PYEOF'
|
|
import sys
|
|
compose_file = sys.argv[1]
|
|
content = open(compose_file).read()
|
|
has_llm_url = 'LLM_URL' in content
|
|
has_llm_model = 'LLM_MODEL' in content
|
|
sys.exit(0 if (has_llm_url and has_llm_model) else 1)
|
|
PYEOF
|
|
ENV_ALREADY=$?
|
|
|
|
if [ $ENV_ALREADY -eq 0 ]; then
|
|
echo "LLM_URL and LLM_MODEL already present in docker-compose.yml"
|
|
else
|
|
read -rp "Enter Ollama URL (default: http://ollama:11434/v1/chat/completions): " llm_url
|
|
llm_url="${llm_url:-http://ollama:11434/v1/chat/completions}"
|
|
|
|
read -rp "Enter model name (default: qwen3.5:9b): " llm_model
|
|
llm_model="${llm_model:-qwen3.5:9b}"
|
|
|
|
python3 - "$COMPOSE_FILE" "$llm_url" "$llm_model" <<'PYEOF'
|
|
import re, sys
|
|
compose_file, llm_url, llm_model = sys.argv[1], sys.argv[2], sys.argv[3]
|
|
content = open(compose_file).read()
|
|
env_lines = f' - LLM_URL={llm_url}\n - LLM_MODEL={llm_model}'
|
|
if 'LLM_URL' not in content:
|
|
content = re.sub(
|
|
r'(environment:(?:\n\s+- [^\n]+)*)',
|
|
lambda m: m.group(0) + '\n' + env_lines,
|
|
content, count=1
|
|
)
|
|
open(compose_file, 'w').write(content)
|
|
print(f'Added LLM_URL={llm_url} and LLM_MODEL={llm_model} to docker-compose.yml')
|
|
else:
|
|
print('LLM_URL already present, skipping')
|
|
PYEOF
|
|
fi
|
|
|
|
# ============================================================
|
|
echo "=== Step 9: Restart SearXNG ==="
|
|
# ============================================================
|
|
read -rp "Restart SearXNG now? (y/n): " restart_choice
|
|
if [[ "$restart_choice" =~ ^[Yy]$ ]]; then
|
|
echo "Restarting SearXNG..."
|
|
cd "$COMPOSE_DIR"
|
|
docker compose up -d --force-recreate core
|
|
echo "SearXNG restarted."
|
|
else
|
|
echo "Skipping restart. Run manually:"
|
|
echo " cd \"$COMPOSE_DIR\" && docker compose up -d --force-recreate core"
|
|
fi
|
|
|
|
# ============================================================
|
|
echo ""
|
|
echo "=== Installation complete ==="
|
|
echo ""
|
|
echo "Summary:"
|
|
echo " Plugin: $PLUGINS_DIR/ollama_answers.py"
|
|
echo " Compose: $COMPOSE_FILE"
|
|
[ -n "$SETTINGS_FILE" ] && echo " Settings: $SETTINGS_FILE"
|
|
echo ""
|
|
echo "Environment variables to verify in docker-compose.yml:"
|
|
echo " LLM_URL — Ollama endpoint"
|
|
echo " LLM_MODEL — Model name (e.g. qwen3.5:9b)"
|
|
echo ""
|