SPB Git

spb/ka-guardian

Public
9.0 KB · 194 lines shellscript
1#!/bin/zsh2# ============================================3# KA Guardian — déploiement complet depuis le laptop4#   ./deploy.sh runners        → runners sur M3U96a M3U96b M4M64a M4M64b5#   ./deploy.sh orchestrators  → ka2/ka4/ka6 sur M4M36 (remplace les anciens bots)6#   ./deploy.sh all7# Idempotent. Le token partagé vit dans ~/.ka-guardian.env (laptop) et est8# poussé sur chaque nœud. Les tunnels ngrok existants (www.kaX.bot) sont gardés.9# ============================================10set -e11ROOT="$(cd "$(dirname "$0")/.." && pwd)"12RUNNER_NODES=(M3U96a M3U96b M4M64a M4M64b)13ORCH_NODE=M4M3614PY=/opt/homebrew/bin/python31516# --- token partagé17TOKEN_FILE="$HOME/.ka-guardian.env"18if [[ ! -f $TOKEN_FILE ]]; then19  echo "KA_GUARDIAN_TOKEN=$(openssl rand -hex 24)" > "$TOKEN_FILE"20  echo "token généré → $TOKEN_FILE"21fi22TOKEN_LINE=$(grep KA_GUARDIAN_TOKEN "$TOKEN_FILE")2324deploy_courier() {25  # Courrier zsh sur TOUS les nœuds (orchestrateur + runners): expédie le26  # trafic LAN inter-nœuds via ssh (macOS 26 Local Network Privacy).27  for n in $RUNNER_NODES $ORCH_NODE; do28    echo "=== courrier → $n"29    scp -q "$ROOT/deploy/courier.sh" $n:ka-guardian-courier.sh30    ssh $n 'chmod +x ~/ka-guardian-courier.sh31      cat > ~/Library/LaunchAgents/com.ka.guardian-courier.plist <<PLIST32<?xml version="1.0" encoding="UTF-8"?>33<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">34<plist version="1.0"><dict>35  <key>Label</key><string>com.ka.guardian-courier</string>36  <key>ProgramArguments</key><array>37    <string>/bin/zsh</string>38    <string>/Users/simon-pierreboucher/ka-guardian-courier.sh</string>39  </array>40  <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>41  <key>StandardOutPath</key><string>/Users/simon-pierreboucher/ka-guardian-spool/courier.log</string>42  <key>StandardErrorPath</key><string>/Users/simon-pierreboucher/ka-guardian-spool/courier.log</string>43</dict></plist>44PLIST45      mkdir -p ~/ka-guardian-spool46      launchctl unload ~/Library/LaunchAgents/com.ka.guardian-courier.plist 2>/dev/null || true47      launchctl load ~/Library/LaunchAgents/com.ka.guardian-courier.plist' \48      && echo " ✓ $n courrier ok" || echo " ✗ $n courrier KO"49  done50}5152deploy_runners() {53  for n in $RUNNER_NODES; do54    echo "=== runner → $n"55    # GOTCHA: redémarrer un runner TUE la mission claude en cours (cause de la56    # mission fantôme du 2026-08-23). On refuse si le runner est occupé.57    busy=$(ssh $n "curl -s -m 5 localhost:7791/health 2>/dev/null" | grep -o '"busy":true' || true)58    if [[ -n $busy ]]; then59      echo " ⏸ $n occupé (mission en cours) — runner NON redéployé, relance plus tard"60      continue61    fi62    ssh $n "mkdir -p ~/ka-guardian-runner/transcripts"63    scp -q "$ROOT/runner/runner.py" $n:ka-guardian-runner/runner.py64    ssh $n "printf '%s\nKA_GUARDIAN_NODE=%s\n' '$TOKEN_LINE' '$n' > ~/.ka-guardian.env65      cd ~/ka-guardian-runner66      [[ -d .venv ]] || $PY -m venv .venv67      ./.venv/bin/pip -q install 'fastapi>=0.110' 'uvicorn>=0.29' 'httpx>=0.27' 'pydantic>=2' >/dev/null68      cat > ~/Library/LaunchAgents/com.ka.guardian-runner.plist <<'PLIST'69<?xml version=\"1.0\" encoding=\"UTF-8\"?>70<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">71<plist version=\"1.0\"><dict>72  <key>Label</key><string>com.ka.guardian-runner</string>73  <key>ProgramArguments</key><array>74    <string>/Users/simon-pierreboucher/ka-guardian-runner/.venv/bin/python</string>75    <string>/Users/simon-pierreboucher/ka-guardian-runner/runner.py</string>76  </array>77  <key>EnvironmentVariables</key><dict>78    <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>79  </dict>80  <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>81  <key>StandardOutPath</key><string>/Users/simon-pierreboucher/ka-guardian-runner/runner.log</string>82  <key>StandardErrorPath</key><string>/Users/simon-pierreboucher/ka-guardian-runner/runner.log</string>83</dict></plist>84PLIST85      launchctl unload ~/Library/LaunchAgents/com.ka.guardian-runner.plist 2>/dev/null || true86      launchctl load ~/Library/LaunchAgents/com.ka.guardian-runner.plist"87    sleep 288    ssh $n "curl -sf localhost:7791/health" && echo " ✓ $n runner ok" || echo " ✗ $n runner KO"89  done90}9192deploy_orchestrators() {93  echo "=== orchestrateurs → $ORCH_NODE"94  ssh $ORCH_NODE "printf '%s\n' '$TOKEN_LINE' > ~/.ka-guardian.env; mkdir -p ~/cluster-projects/ka-guardian"95  cd "$ROOT"96  # tar-over-ssh: déterministe (gotcha: rsync silencieusement inopérant depuis97  # ce contexte de script — jamais élucidé, contourné définitivement).98  tar czf - --exclude data --exclude .venv --exclude .git --exclude '__pycache__' --exclude logs . \99    | ssh $ORCH_NODE 'tar xzf - -C ~/cluster-projects/ka-guardian/'100  loc=$(md5 -q orchestrator/main.py); rem=$(ssh $ORCH_NODE 'md5 -q ~/cluster-projects/ka-guardian/orchestrator/main.py')101  [[ "$loc" == "$rem" ]] || { echo "✗ transfert raté: main.py ($loc ≠ $rem)"; exit 1; }102  ssh $ORCH_NODE "cd ~/cluster-projects/ka-guardian103    PY=\$(command -v /opt/homebrew/bin/python3 || command -v /opt/homebrew/bin/python3.13)104    [[ -d .venv ]] || \$PY -m venv .venv105    ./.venv/bin/pip -q install 'fastapi>=0.110' 'uvicorn>=0.29' 'httpx>=0.27' >/dev/null106    mkdir -p data logs107    # retirer les anciens bots (web+bot), garder les tunnels ngrok108    for a in ka2 ka4 ka6; do109      launchctl unload ~/Library/LaunchAgents/com.\$a.web.plist 2>/dev/null || true110      launchctl unload ~/Library/LaunchAgents/com.\$a.bot.plist 2>/dev/null || true111      rm -f ~/Library/LaunchAgents/com.\$a.web.plist ~/Library/LaunchAgents/com.\$a.bot.plist112    done"113  for a in ka2:8799 ka4:8899 ka6:8999; do114    agent=${a%%:*}; port=${a##*:}115    ssh $ORCH_NODE "cat > ~/Library/LaunchAgents/com.$agent.guardian.plist <<PLIST116<?xml version=\"1.0\" encoding=\"UTF-8\"?>117<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">118<plist version=\"1.0\"><dict>119  <key>Label</key><string>com.$agent.guardian</string>120  <key>ProgramArguments</key><array>121    <string>/Users/simon-pierreboucher/cluster-projects/ka-guardian/.venv/bin/python</string>122    <string>/Users/simon-pierreboucher/cluster-projects/ka-guardian/orchestrator/main.py</string>123  </array>124  <key>EnvironmentVariables</key><dict>125    <key>AGENT</key><string>$agent</string>126    <key>KA_GUARDIAN_SELF_IP</key><string>192.168.2.69</string>127    <key>PATH</key><string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>128  </dict>129  <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>130  <key>StandardOutPath</key><string>/Users/simon-pierreboucher/cluster-projects/ka-guardian/logs/$agent.log</string>131  <key>StandardErrorPath</key><string>/Users/simon-pierreboucher/cluster-projects/ka-guardian/logs/$agent.log</string>132</dict></plist>133PLIST134      launchctl unload ~/Library/LaunchAgents/com.$agent.guardian.plist 2>/dev/null || true135      launchctl load ~/Library/LaunchAgents/com.$agent.guardian.plist"136    sleep 2137    ssh $ORCH_NODE "curl -sf localhost:$port/health" && echo " ✓ $agent ok (:$port)" || echo " ✗ $agent KO"138  done139}140141deploy_pousseur() {142  # Pousseur launchd (binaires Apple) : pousse les commits en attente des repos143  # Ka du nœud — les missions Claude ne peuvent pas pousser elles-mêmes144  # (macOS 26 Local Network Privacy bloque les descendants du runner python).145  typeset -A REPOS146  REPOS[M3U96a]='~/apps/vrai-prix147~/apps/sorti-ka148~/apps/job-ka'149  REPOS[M3U96b]='~/apps/groupe-ka150~/apps/lou-ka151/opt/api-ka152~/apps/crea-ka153~/apps/resto-ka'154  REPOS[M4M64a]='~/apps/immo-ka155~/fabri-ka'156  REPOS[M4M64b]='~/auto-ka157~/apps/food-ka'158  for n in $RUNNER_NODES; do159    echo "=== pousseur → $n"160    scp -q "$ROOT/deploy/pousseur.sh" $n:ka-pousseur.sh161    ssh $n "chmod +x ~/ka-pousseur.sh162      cat > ~/.ka-pousseur-repos <<'REPOS'163${REPOS[$n]}164REPOS165      cat > ~/Library/LaunchAgents/com.ka.pousseur.plist <<'PLIST'166<?xml version=\"1.0\" encoding=\"UTF-8\"?>167<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">168<plist version=\"1.0\"><dict>169  <key>Label</key><string>com.ka.pousseur</string>170  <key>ProgramArguments</key><array>171    <string>/bin/zsh</string>172    <string>/Users/simon-pierreboucher/ka-pousseur.sh</string>173  </array>174  <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>175  <key>StandardOutPath</key><string>/Users/simon-pierreboucher/ka-guardian-spool/pousseur.log</string>176  <key>StandardErrorPath</key><string>/Users/simon-pierreboucher/ka-guardian-spool/pousseur.log</string>177</dict></plist>178PLIST179      mkdir -p ~/ka-guardian-spool180      launchctl unload ~/Library/LaunchAgents/com.ka.pousseur.plist 2>/dev/null || true181      launchctl load ~/Library/LaunchAgents/com.ka.pousseur.plist" \182      && echo " ✓ $n pousseur ok" || echo " ✗ $n pousseur KO"183  done184}185186case "${1:-all}" in187  courier) deploy_courier ;;188  runners) deploy_runners ;;189  orchestrators) deploy_orchestrators ;;190  pousseur) deploy_pousseur ;;191  all) deploy_courier; deploy_runners; deploy_orchestrators; deploy_pousseur ;;192esac193echo "terminé."194
Files · 990818c8665a84cd9a03173c8e3f3ad3a9f6baaf
Menu

Theme