#!/usr/bin/env bash # Dependency probe for golangLAKEHOUSE. # Sprint 0 / S0.1 — surfaces every cold-start dep as a structured # checklist. With --json, emits machine-readable shape for CI. # # Exit 0 = all green. Exit 1 = at least one missing dep. set -uo pipefail # Mode: text (default) or json JSON=0 for arg in "$@"; do case "$arg" in --json) JSON=1 ;; -h|--help) echo "Usage: $0 [--json]" echo " Probes Go, gcc, MinIO, Ollama, secrets-go.toml." echo " Default output is human-readable; --json emits structured findings." exit 0 ;; esac done # Findings accumulator. Each entry: ||| # status ∈ {ok, missing, wrong-version, unreachable} findings=() probe() { findings+=("$1|$2|$3|$4") } # 1. Go ≥1.25 (arrow-go pulled the floor up — see ADR-001 §1.x) if go_path="$(command -v go 2>/dev/null)"; then go_ver="$(go version 2>/dev/null | awk '{print $3}' | sed 's/^go//')" case "$go_ver" in 1.25*|1.26*|1.27*) probe "go" "ok" "$go_ver at $go_path" "" ;; *) probe "go" "wrong-version" "$go_ver at $go_path (need ≥1.25)" \ "curl -L https://go.dev/dl/go1.25.0.linux-amd64.tar.gz | sudo tar -C /usr/local -xz" ;; esac else probe "go" "missing" "not in PATH" \ "curl -L https://go.dev/dl/go1.25.0.linux-amd64.tar.gz | sudo tar -C /usr/local -xz && export PATH=\$PATH:/usr/local/go/bin" fi # 2. gcc (DuckDB cgo binding per ADR-001 §1.1) if gcc_path="$(command -v gcc 2>/dev/null)"; then gcc_ver="$(gcc --version 2>/dev/null | head -1 | awk '{print $NF}')" probe "gcc" "ok" "$gcc_ver at $gcc_path" "" else probe "gcc" "missing" "not in PATH" "sudo apt install -y build-essential" fi # 3. MinIO at :9000 with bucket lakehouse-go-primary if curl -sf --max-time 2 http://localhost:9000/minio/health/live >/dev/null 2>&1; then # bucket existence — use mc if available, else fall back to noting it if command -v mc >/dev/null 2>&1; then if mc ls local/lakehouse-go-primary >/dev/null 2>&1; then probe "minio" "ok" "live at :9000, bucket lakehouse-go-primary present" "" else probe "minio" "missing" "live at :9000 but bucket lakehouse-go-primary absent" \ "mc mb local/lakehouse-go-primary" fi else probe "minio" "ok" "live at :9000 (bucket presence not verified — install mc to check)" "" fi else probe "minio" "unreachable" "no /minio/health/live response on :9000" \ "sudo systemctl start minio # or restart" fi # 4. Ollama at :11434 with nomic-embed-text loaded (G2 default model) if ollama_resp="$(curl -sf --max-time 3 http://localhost:11434/api/tags 2>/dev/null)"; then if echo "$ollama_resp" | grep -q '"name":"nomic-embed-text:latest"'; then probe "ollama" "ok" "live at :11434, nomic-embed-text loaded" "" else probe "ollama" "missing" "live at :11434 but nomic-embed-text not loaded" \ "ollama pull nomic-embed-text" fi else probe "ollama" "unreachable" "no /api/tags response on :11434" \ "sudo systemctl start ollama" fi # 5. /etc/lakehouse/secrets-go.toml if [ -f /etc/lakehouse/secrets-go.toml ]; then if [ -r /etc/lakehouse/secrets-go.toml ]; then if grep -q '\[s3.primary\]' /etc/lakehouse/secrets-go.toml 2>/dev/null; then probe "secrets" "ok" "/etc/lakehouse/secrets-go.toml present, contains [s3.primary]" "" else probe "secrets" "missing" "/etc/lakehouse/secrets-go.toml missing [s3.primary] section" \ "edit /etc/lakehouse/secrets-go.toml to add [s3.primary] with access_key_id + secret_access_key" fi else probe "secrets" "missing" "/etc/lakehouse/secrets-go.toml exists but unreadable by current user" \ "sudo chmod 0644 /etc/lakehouse/secrets-go.toml # or run as the user that can read it" fi else probe "secrets" "missing" "/etc/lakehouse/secrets-go.toml not present" \ "sudo install -m 0644 /dev/stdin /etc/lakehouse/secrets-go.toml < secrets-go.toml.example" fi # Summarize exit_code=0 for f in "${findings[@]}"; do case "$(echo "$f" | cut -d'|' -f2)" in ok) ;; *) exit_code=1 ;; esac done if [ "$JSON" -eq 1 ]; then printf '{\n' printf ' "deps": [\n' last=$((${#findings[@]} - 1)) for i in "${!findings[@]}"; do IFS='|' read -r name status detail fix <<< "${findings[$i]}" printf ' {"name":"%s","status":"%s","detail":"%s","fix":"%s"}' \ "$name" "$status" \ "$(echo "$detail" | sed 's/"/\\"/g')" \ "$(echo "$fix" | sed 's/"/\\"/g')" [ "$i" -lt "$last" ] && printf ',' printf '\n' done printf ' ],\n' printf ' "ok": %s\n' "$([ $exit_code -eq 0 ] && echo true || echo false)" printf '}\n' else echo "[doctor] dependency probe:" for f in "${findings[@]}"; do IFS='|' read -r name status detail fix <<< "$f" case "$status" in ok) printf " ✓ %-7s %s\n" "$name" "$detail" ;; missing) printf " ✗ %-7s %s\n" "$name" "$detail" [ -n "$fix" ] && printf " fix: %s\n" "$fix" ;; wrong-version) printf " ⚠ %-7s %s\n" "$name" "$detail" [ -n "$fix" ] && printf " fix: %s\n" "$fix" ;; unreachable) printf " ✗ %-7s %s\n" "$name" "$detail" [ -n "$fix" ] && printf " fix: %s\n" "$fix" ;; esac done if [ "$exit_code" -eq 0 ]; then echo "[doctor] all dependencies green" else echo "[doctor] one or more dependencies need attention" fi fi exit "$exit_code"