#!/usr/bin/env bash set -euo pipefail REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" if [[ "$(id -u)" -eq 0 ]]; then echo "Run this as your normal Ubuntu user, not root." >&2 exit 2 fi discover_windows_host(){ local src prefix network candidate src="$(ip -4 route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')" prefix="$(ip -4 -o addr show scope global | awk 'NR==1{print $4}' | cut -d/ -f2)" if [[ -n "$src" && -n "$prefix" && "$prefix" -ge 24 ]]; then network="$(echo "$src" | awk -F. '{print $1"."$2"."$3}')" candidate="$network.1" if curl -fsS --connect-timeout 2 "http://$candidate:11434/api/tags" >/dev/null 2>&1; then printf '%s' "$candidate" return fi fi local gw gw="$(ip route | awk '/default/ {print $3; exit}')" if [[ -n "$gw" ]] && curl -fsS --connect-timeout 2 "http://$gw:11434/api/tags" >/dev/null 2>&1; then printf '%s' "$gw" fi } if [[ -z "${WINDOWS_HOST_IP:-}" ]]; then WINDOWS_HOST_IP="$(discover_windows_host || true)" fi if ! sudo -n true 2>/dev/null; then echo "This setup needs sudo for Docker/packages. Ubuntu may ask for your password." fi echo "==> Installing Ubuntu prerequisites" sudo apt-get update sudo DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl git jq openssl python3 unzip lvm2 echo "==> Expanding Ubuntu root LVM to use free virtual-disk space" ROOT_DEV="$(findmnt -n -o SOURCE / || true)" if [[ "$ROOT_DEV" == /dev/mapper/* ]] && command -v lvs >/dev/null 2>&1; then FREE_BYTES="$(sudo vgs --noheadings --units b --nosuffix -o vg_free 2>/dev/null | awk '{sum+=$1} END{printf "%.0f",sum}')" if [[ "${FREE_BYTES:-0}" -gt 1073741824 ]]; then sudo lvextend -l +100%FREE -r "$ROOT_DEV" fi fi df -h / if ! command -v node >/dev/null 2>&1 || [[ "$(node -p 'process.versions.node.split(".")[0]' 2>/dev/null || echo 0)" -lt 22 ]]; then echo "==> Installing Node.js 22" curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash - sudo DEBIAN_FRONTEND=noninteractive apt-get install -y nodejs fi if ! command -v pnpm >/dev/null 2>&1; then echo "==> Installing pnpm" sudo corepack enable sudo corepack prepare pnpm@11.25.0 --activate fi echo "Node: $(node --version)" echo "pnpm: $(pnpm --version)" if ! command -v docker >/dev/null 2>&1; then echo "==> Installing Docker Engine" curl -fsSL https://get.docker.com | sudo sh sudo usermod -aG docker "$USER" echo echo "Docker was installed and your user was added to the docker group." echo "Log out of Ubuntu and back in, then rerun this script." exit 20 fi if ! docker info >/dev/null 2>&1; then echo "Docker exists but this user cannot access it yet." echo "Log out of Ubuntu and back in, then rerun this script." exit 21 fi echo "==> Checking Windows-hosted Ollama" OLLAMA_AVAILABLE=0 if [[ -n "${WINDOWS_HOST_IP:-}" ]] && curl -fsS --connect-timeout 4 "http://$WINDOWS_HOST_IP:11434/api/tags" >/tmp/ollama-tags.json; then OLLAMA_AVAILABLE=1 echo "Ollama reachable at http://$WINDOWS_HOST_IP:11434" else echo "Windows Ollama is not reachable yet. Continuing with deterministic AzerothAI decisions." echo "The game realm can boot first; Qwen can be connected afterward without rebuilding AzerothCore." fi echo "==> Bootstrapping playable AzerothAI realm" export AZEROTHAI_PLAYABLE_ROOT="${AZEROTHAI_PLAYABLE_ROOT:-$HOME/azerothai-pc-lab}" bash "$REPO_ROOT/deploy/playable/bootstrap.sh" LAB_ROOT="$AZEROTHAI_PLAYABLE_ROOT" if [[ "$OLLAMA_AVAILABLE" -eq 1 ]]; then echo "==> Pointing AzerothAI at Qwen on the Windows RTX host" DEV_VARS="$REPO_ROOT/.dev.vars" python3 - "$DEV_VARS" "http://$WINDOWS_HOST_IP:11434" <<'PY' from pathlib import Path import sys p=Path(sys.argv[1]) value=sys.argv[2] lines=p.read_text().splitlines() if p.exists() else [] out=[] found=False for line in lines: if line.startswith("LLM_URL="): out.append("LLM_URL="+value) found=True else: out.append(line) if not found: out.append("LLM_URL="+value) p.write_text("\n".join(out).rstrip()+"\n") PY chmod 600 "$DEV_VARS" echo "==> Restarting AzerothAI runtime with host Ollama endpoint" if [[ -f "$LAB_ROOT/azerothai.pid" ]]; then pid="$(cat "$LAB_ROOT/azerothai.pid")" kill "$pid" 2>/dev/null || true sleep 1 fi cd "$REPO_ROOT" nohup pnpm start:lan >"$LAB_ROOT/azerothai.log" 2>&1 & echo $! > "$LAB_ROOT/azerothai.pid" for _ in {1..60}; do if curl -fsS http://127.0.0.1:8787/api/health >/tmp/azerothai-health.json 2>/dev/null; then break; fi sleep 1 done fi VM_IP="$(hostname -I | awk '{print $1}')" echo echo "============================================================" echo " TEMPORARY PC LAB READY" echo "============================================================" echo "Ubuntu VM IP : $VM_IP" echo "Windows host : ${WINDOWS_HOST_IP:-not connected yet}" if [[ "$OLLAMA_AVAILABLE" -eq 1 ]]; then echo "Ollama : http://$WINDOWS_HOST_IP:11434" else echo "Ollama : not connected yet (realm still usable)" fi echo echo "Next:" echo " 1. Create your WoW/GM account using the worldserver console." echo " 2. Put the Ubuntu VM IP into Windows WoW realmlist.wtf." echo " 3. Open AzerothAI World Monitor from Windows/iPad:" echo " http://$VM_IP:8787" echo echo "Check everything:" echo " AZEROTHAI_PLAYABLE_ROOT=$AZEROTHAI_PLAYABLE_ROOT bash deploy/playable/status.sh"