mirror of
https://github.com/dredx/prole.git
synced 2026-09-23 11:03:59 +00:00
- Moved files from 'prole/' subdirectory to root level or appropriate subdirectories (tests, authority, infrastructure) to flatten the project structure. - Updated 'install.py' and initialization scripts in 'etc/' to reflect the new directory layout. - Added 'etc/repair_pipeline.sh' for automated pipeline repairs. - Updated configuration files including 'conf/prole.cfg' and 'env.sh'. - Integrated ArgoCD manifests in 'k8s/argocd/'. - Updated 'prole-app' environment and properties. - Moved and updated test scripts for better organization and reliability. - Added 'tests/silent_install_test.sh' for automated installation testing.
262 lines
6.0 KiB
Bash
262 lines
6.0 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
|
PROJECT_ROOT=$(cd "$SCRIPT_DIR/.." && pwd)
|
|
|
|
# Load config/environment defaults if available
|
|
if [[ -f "$SCRIPT_DIR/prole_cfg.sh" ]]; then
|
|
# shellcheck disable=SC1090
|
|
source "$SCRIPT_DIR/prole_cfg.sh"
|
|
fi
|
|
|
|
action="${1:-scan}"
|
|
shift || true
|
|
|
|
DEFAULT_PORT="11434"
|
|
port="${OLLAMA_SERVER_PORT:-$DEFAULT_PORT}"
|
|
timeout="${OLLAMA_SCAN_TIMEOUT:-2}"
|
|
max_hosts="${OLLAMA_SCAN_MAX_HOSTS:-64}"
|
|
hosts_file=""
|
|
explicit_host=""
|
|
explicit_model=""
|
|
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 [scan|configure] [options]
|
|
|
|
Options:
|
|
--host <host> Explicit host (optionally host:port)
|
|
--port <port> Default port (default: ${DEFAULT_PORT})
|
|
--hosts-file <path> Hosts file to scan (default: PROLE_CONF/hosts.txt or etc/hosts.txt)
|
|
--timeout <seconds> Curl timeout (default: ${timeout})
|
|
--max-hosts <n> Max hosts to probe (default: ${max_hosts})
|
|
--model <name> Preferred model (configure action)
|
|
|
|
Env:
|
|
OLLAMA_HOST, OLLAMA_SERVER_HOST, OLLAMA_SERVER_PORT, OLLAMA_CANDIDATES
|
|
EOF
|
|
}
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--host)
|
|
explicit_host="${2:-}"
|
|
shift 2
|
|
;;
|
|
--port)
|
|
port="${2:-}"
|
|
shift 2
|
|
;;
|
|
--hosts-file)
|
|
hosts_file="${2:-}"
|
|
shift 2
|
|
;;
|
|
--timeout)
|
|
timeout="${2:-}"
|
|
shift 2
|
|
;;
|
|
--max-hosts)
|
|
max_hosts="${2:-}"
|
|
shift 2
|
|
;;
|
|
--model)
|
|
explicit_model="${2:-}"
|
|
shift 2
|
|
;;
|
|
--help|-h)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
shift
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ -z "$port" ]]; then
|
|
port="$DEFAULT_PORT"
|
|
fi
|
|
|
|
normalize_host() {
|
|
local raw="$1"
|
|
raw="${raw#http://}"
|
|
raw="${raw#https://}"
|
|
raw="${raw%%/*}"
|
|
printf '%s' "$raw"
|
|
}
|
|
|
|
split_host_port() {
|
|
local raw host port_val
|
|
raw=$(normalize_host "$1")
|
|
host="$raw"
|
|
port_val=""
|
|
if [[ "$raw" == *":"* ]]; then
|
|
host="${raw%%:*}"
|
|
port_val="${raw##*:}"
|
|
fi
|
|
printf '%s\t%s' "$host" "$port_val"
|
|
}
|
|
|
|
seen="|"
|
|
pairs=()
|
|
|
|
add_pair() {
|
|
local host="$1"
|
|
local port_val="$2"
|
|
host="$(printf '%s' "$host" | tr -d '[:space:]')"
|
|
if [[ -z "$host" ]]; then
|
|
return
|
|
fi
|
|
if [[ -z "$port_val" ]]; then
|
|
port_val="$port"
|
|
fi
|
|
local key="${host}:${port_val}"
|
|
if [[ "$seen" == *"|$key|"* ]]; then
|
|
return
|
|
fi
|
|
seen="${seen}${key}|"
|
|
pairs+=("$key")
|
|
}
|
|
|
|
add_candidates() {
|
|
local list="$1"
|
|
local entry host port_val
|
|
for entry in $(printf '%s' "$list" | tr ',;' ' '); do
|
|
if [[ -z "$entry" ]]; then
|
|
continue
|
|
fi
|
|
IFS=$'\t' read -r host port_val < <(split_host_port "$entry")
|
|
add_pair "$host" "$port_val"
|
|
done
|
|
}
|
|
|
|
if [[ -n "$explicit_host" ]]; then
|
|
IFS=$'\t' read -r host port_val < <(split_host_port "$explicit_host")
|
|
add_pair "$host" "$port_val"
|
|
fi
|
|
|
|
if [[ -n "${OLLAMA_HOST:-}" ]]; then
|
|
IFS=$'\t' read -r host port_val < <(split_host_port "$OLLAMA_HOST")
|
|
add_pair "$host" "$port_val"
|
|
fi
|
|
|
|
if [[ -n "${OLLAMA_SERVER_HOST:-}" ]]; then
|
|
add_pair "$OLLAMA_SERVER_HOST" "$port"
|
|
fi
|
|
|
|
if [[ -n "${OLLAMA_CANDIDATES:-}" ]]; then
|
|
add_candidates "$OLLAMA_CANDIDATES"
|
|
fi
|
|
|
|
if [[ -z "$hosts_file" ]]; then
|
|
if [[ -n "${PROLE_CONF:-}" && -f "$PROLE_CONF/hosts.txt" ]]; then
|
|
hosts_file="$PROLE_CONF/hosts.txt"
|
|
elif [[ -f "$SCRIPT_DIR/hosts.txt" ]]; then
|
|
hosts_file="$SCRIPT_DIR/hosts.txt"
|
|
elif [[ -f "$PROJECT_ROOT/etc/hosts.txt" ]]; then
|
|
hosts_file="$PROJECT_ROOT/etc/hosts.txt"
|
|
fi
|
|
fi
|
|
|
|
if [[ -n "$hosts_file" && -f "$hosts_file" ]]; then
|
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
line="${line%%#*}"
|
|
line="$(printf '%s' "$line" | xargs)"
|
|
[[ -z "$line" ]] && continue
|
|
read -r first second _rest <<<"$line"
|
|
[[ -z "$first" ]] && continue
|
|
if [[ "$first" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
add_pair "$second" "$port"
|
|
add_pair "$first" "$port"
|
|
else
|
|
add_pair "$first" "$port"
|
|
if [[ -n "$second" ]]; then
|
|
add_pair "$second" "$port"
|
|
fi
|
|
fi
|
|
done <"$hosts_file"
|
|
fi
|
|
|
|
if [[ -f "/etc/hosts" ]]; then
|
|
while IFS= read -r line || [[ -n "$line" ]]; do
|
|
line="${line%%#*}"
|
|
line="$(printf '%s' "$line" | xargs)"
|
|
[[ -z "$line" ]] && continue
|
|
read -r first second _rest <<<"$line"
|
|
[[ -z "$first" || -z "$second" ]] && continue
|
|
if [[ "$first" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
|
|
add_pair "$second" "$port"
|
|
add_pair "$first" "$port"
|
|
fi
|
|
done <"/etc/hosts"
|
|
fi
|
|
|
|
scan_pairs() {
|
|
local count=0
|
|
local pair host port_val url json models
|
|
for pair in "${pairs[@]}"; do
|
|
if [[ "$count" -ge "$max_hosts" ]]; then
|
|
break
|
|
fi
|
|
host="${pair%%:*}"
|
|
port_val="${pair##*:}"
|
|
url="http://${host}:${port_val}/api/tags"
|
|
if ! json=$(curl -fsS --connect-timeout "$timeout" --max-time "$timeout" "$url" 2>/dev/null); then
|
|
continue
|
|
fi
|
|
if ! models=$(printf '%s' "$json" | python3 - <<'PY'
|
|
import json
|
|
import sys
|
|
data = sys.stdin.read().strip()
|
|
if not data:
|
|
sys.exit(1)
|
|
try:
|
|
payload = json.loads(data)
|
|
except Exception:
|
|
sys.exit(1)
|
|
if not isinstance(payload, dict) or "models" not in payload:
|
|
sys.exit(1)
|
|
models = []
|
|
for entry in payload.get("models", []):
|
|
name = entry.get("name") or entry.get("model") or ""
|
|
if name:
|
|
models.append(name)
|
|
print(",".join(models))
|
|
PY
|
|
); then
|
|
continue
|
|
fi
|
|
printf '%s\t%s\t%s\n' "$host" "$port_val" "$models"
|
|
count=$((count + 1))
|
|
done
|
|
}
|
|
|
|
case "$action" in
|
|
scan)
|
|
scan_pairs
|
|
;;
|
|
configure)
|
|
first_line="$(scan_pairs | head -n 1)"
|
|
if [[ -z "$first_line" ]]; then
|
|
exit 1
|
|
fi
|
|
host="$(printf '%s' "$first_line" | awk -F'\t' '{print $1}')"
|
|
port_val="$(printf '%s' "$first_line" | awk -F'\t' '{print $2}')"
|
|
models="$(printf '%s' "$first_line" | awk -F'\t' '{print $3}')"
|
|
if [[ -z "$explicit_model" ]]; then
|
|
explicit_model="${models%%,*}"
|
|
fi
|
|
echo "OLLAMA_SERVER_HOST=${host}"
|
|
echo "OLLAMA_SERVER_PORT=${port_val}"
|
|
echo "OLLAMA_HOST=http://${host}:${port_val}"
|
|
if [[ -n "$explicit_model" ]]; then
|
|
echo "OLLAMA_MODEL=${explicit_model}"
|
|
fi
|
|
;;
|
|
*)
|
|
usage
|
|
exit 2
|
|
;;
|
|
esac
|