- Root setup.sh orchestrator with per-phase dispatch (./setup.sh p1..p8 | all | status) - Makefile convenience targets (make infra, make llm, make status, etc.) - scripts/common.sh: shared bash library for OS detection, Docker helpers, service management (launchd/systemd), package install, env management - .env.example + .gitignore: shared config template and secret exclusions P1 (homeai-infra): full implementation - docker-compose.yml: Uptime Kuma, code-server, n8n - Note: Home Assistant, Portainer, Gitea are pre-existing instances - setup.sh: Docker install, homeai network, container health checks P2 (homeai-llm): full implementation - Ollama native install with CUDA/ROCm/Metal auto-detection - launchd plist (macOS) + systemd service (Linux) for auto-start - scripts/pull-models.sh: idempotent model puller from manifest - scripts/benchmark.sh: tokens/sec measurement per model - Open WebUI on port 3030 (avoids Gitea :3000 conflict) P3-P8: working stubs with prerequisite checks and TODO sections Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
141 lines
4.0 KiB
Bash
141 lines
4.0 KiB
Bash
#!/usr/bin/env bash
|
|
# setup.sh — HomeAI root orchestrator
|
|
#
|
|
# Usage:
|
|
# ./setup.sh all # run all phases in order
|
|
# ./setup.sh p1 # infra only
|
|
# ./setup.sh p2 # llm only
|
|
# ./setup.sh p1 p2 # multiple phases
|
|
# ./setup.sh status # show service health
|
|
#
|
|
# Phases: p1=infra p2=llm p3=voice p4=agent p5=character
|
|
# p6=esp32 p7=visual p8=images
|
|
|
|
set -euo pipefail
|
|
|
|
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
# shellcheck source=scripts/common.sh
|
|
source "${REPO_DIR}/scripts/common.sh"
|
|
|
|
# ─── Phase definitions ─────────────────────────────────────────────────────────
|
|
declare -A PHASE_NAME=(
|
|
[p1]="homeai-infra (Docker stack)"
|
|
[p2]="homeai-llm (Ollama + Open WebUI)"
|
|
[p3]="homeai-voice (STT / TTS / Wyoming)"
|
|
[p4]="homeai-agent (OpenClaw + skills + mem0)"
|
|
[p5]="homeai-character (Character Manager UI)"
|
|
[p6]="homeai-esp32 (ESPHome firmware)"
|
|
[p7]="homeai-visual (VTube Studio bridge)"
|
|
[p8]="homeai-images (ComfyUI workflows)"
|
|
)
|
|
|
|
PHASE_ORDER=(p1 p2 p3 p4 p5 p6 p7 p8)
|
|
|
|
run_phase() {
|
|
local phase="$1"
|
|
local subdir="${REPO_DIR}/homeai-${phase#p}"
|
|
|
|
# Map phase ID to directory name
|
|
case "$phase" in
|
|
p1) subdir="${REPO_DIR}/homeai-infra" ;;
|
|
p2) subdir="${REPO_DIR}/homeai-llm" ;;
|
|
p3) subdir="${REPO_DIR}/homeai-voice" ;;
|
|
p4) subdir="${REPO_DIR}/homeai-agent" ;;
|
|
p5) subdir="${REPO_DIR}/homeai-character" ;;
|
|
p6) subdir="${REPO_DIR}/homeai-esp32" ;;
|
|
p7) subdir="${REPO_DIR}/homeai-visual" ;;
|
|
p8) subdir="${REPO_DIR}/homeai-images" ;;
|
|
*) die "Unknown phase: $phase" ;;
|
|
esac
|
|
|
|
local setup_script="${subdir}/setup.sh"
|
|
if [[ ! -f "$setup_script" ]]; then
|
|
die "Setup script not found: $setup_script"
|
|
fi
|
|
|
|
log_section "Phase ${phase^^}: ${PHASE_NAME[$phase]}"
|
|
bash "$setup_script"
|
|
}
|
|
|
|
show_status() {
|
|
log_section "HomeAI Service Status"
|
|
|
|
load_env_services
|
|
|
|
local services=(
|
|
"Home Assistant|${HA_URL:-http://localhost:8123}"
|
|
"Portainer|${PORTAINER_URL:-https://localhost:9443}"
|
|
"Uptime Kuma|${UPTIME_KUMA_URL:-http://localhost:3001}"
|
|
"Gitea|${GITEA_URL:-http://localhost:3000}"
|
|
"code-server|${CODE_SERVER_URL:-http://localhost:8090}"
|
|
"n8n|${N8N_URL:-http://localhost:5678}"
|
|
"Ollama|${OLLAMA_URL:-http://localhost:11434}"
|
|
"Open WebUI|${OPEN_WEBUI_URL:-http://localhost:3030}"
|
|
)
|
|
|
|
for entry in "${services[@]}"; do
|
|
local name="${entry%%|*}"
|
|
local url="${entry##*|}"
|
|
if curl -sf --max-time 2 "$url" -o /dev/null 2>/dev/null; then
|
|
printf " ${GREEN}●${RESET} %-20s %s\n" "$name" "$url"
|
|
else
|
|
printf " ${RED}○${RESET} %-20s %s\n" "$name" "$url"
|
|
fi
|
|
done
|
|
echo ""
|
|
}
|
|
|
|
usage() {
|
|
echo ""
|
|
echo " Usage: $0 <phase...> | all | status"
|
|
echo ""
|
|
echo " Phases:"
|
|
for p in "${PHASE_ORDER[@]}"; do
|
|
printf " %-6s %s\n" "$p" "${PHASE_NAME[$p]}"
|
|
done
|
|
echo ""
|
|
echo " Examples:"
|
|
echo " $0 all # setup everything in order"
|
|
echo " $0 p1 p2 # infra + llm only"
|
|
echo " $0 status # check service health"
|
|
echo ""
|
|
}
|
|
|
|
# ─── Main ──────────────────────────────────────────────────────────────────────
|
|
main() {
|
|
if [[ $# -eq 0 ]]; then
|
|
usage
|
|
exit 0
|
|
fi
|
|
|
|
detect_platform
|
|
|
|
# Bootstrap root .env if missing
|
|
bootstrap_env "${REPO_DIR}"
|
|
|
|
local phases=()
|
|
|
|
for arg in "$@"; do
|
|
case "$arg" in
|
|
all) phases=("${PHASE_ORDER[@]}") ;;
|
|
status) show_status; exit 0 ;;
|
|
p[1-8]) phases+=("$arg") ;;
|
|
help|-h|--help) usage; exit 0 ;;
|
|
*) die "Unknown argument: $arg. Run '$0 help' for usage." ;;
|
|
esac
|
|
done
|
|
|
|
if [[ ${#phases[@]} -eq 0 ]]; then
|
|
usage; exit 0
|
|
fi
|
|
|
|
for phase in "${phases[@]}"; do
|
|
run_phase "$phase"
|
|
done
|
|
|
|
log_section "Setup complete"
|
|
show_status
|
|
}
|
|
|
|
main "$@"
|