deploy-gigafactory.sh loads platform-service/.env, starts the fleet backend, waits for /health, and registers the ecosystem products (idempotent) so live /api/fleet/* calls resolve. Supports --stop / --register-only / --no-register. Registered the 11 ecosystem products against the configured Cosmos during a live run; note fleet metrics needs a composite index on real Azure Cosmos. Generated with [Devin](https://cli.devin.ai/docs) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
133 lines
5.1 KiB
Bash
Executable File
133 lines
5.1 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# deploy-gigafactory.sh — one-shot local deploy of the Agent Gigafactory
|
|
# (platform-service fleet module) against the configured backend, then register
|
|
# the ecosystem products so live /api/fleet/* calls return data.
|
|
#
|
|
# Prereqs:
|
|
# - learning_ai_common_plat checked out as a sibling of this repo
|
|
# - services/platform-service/.env filled (Cosmos endpoint/key, JWT_SECRET, ...)
|
|
# e.g. populated from Azure: COSMOS_ENDPOINT/COSMOS_KEY/AZURE_BLOB_CONNECTION_STRING
|
|
# - pnpm deps installed in common_plat; Node 18+
|
|
#
|
|
# Usage:
|
|
# ./deploy-gigafactory.sh # start service, wait for health, register products, smoke
|
|
# ./deploy-gigafactory.sh --register-only # service already running on $PORT; just register products
|
|
# ./deploy-gigafactory.sh --stop # stop a service started by this script
|
|
# ./deploy-gigafactory.sh --no-register # start + health only, skip product registration
|
|
#
|
|
# Env overrides:
|
|
# COMMON_PLAT path to learning_ai_common_plat (default: ../learning_ai_common_plat)
|
|
# PORT platform-service port (default: 4003)
|
|
# PRODUCTS space-separated "id|DisplayName|PREFIX" tuples (default: ecosystem set)
|
|
set -euo pipefail
|
|
|
|
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
COMMON_PLAT="${COMMON_PLAT:-$(cd "$HERE/../../learning_ai_common_plat" 2>/dev/null && pwd || true)}"
|
|
PORT="${PORT:-4003}"
|
|
PS_DIR="$COMMON_PLAT/services/platform-service"
|
|
ENV_FILE="$PS_DIR/.env"
|
|
PID_FILE="$HERE/.gigafactory-platform-service.pid"
|
|
LOG_FILE="${TMPDIR:-/tmp}/gigafactory-platform-service.log"
|
|
BASE="http://localhost:$PORT"
|
|
|
|
PRODUCTS="${PRODUCTS:-\
|
|
lysnrai|LysnrAI|LYS \
|
|
mindlyst|MindLyst|MIND \
|
|
chronomind|ChronoMind|CHR \
|
|
jarvisjr|JarvisJr|JAR \
|
|
nomgap|NomGap|NOM \
|
|
peakpulse|PeakPulse|PEAK \
|
|
flowmonk|FlowMonk|FLOW \
|
|
notelett|NoteLett|NOTE \
|
|
actiontrail|ActionTrail|ACT \
|
|
localmemgpt|LocalMemGPT|LMG \
|
|
efforise|EffoRise|EFF}"
|
|
|
|
die() { echo "error: $*" >&2; exit 1; }
|
|
|
|
stop_service() {
|
|
if [ -f "$PID_FILE" ]; then
|
|
local pid; pid="$(cat "$PID_FILE")"
|
|
if kill -0 "$pid" 2>/dev/null; then kill "$pid" && echo "stopped platform-service (pid $pid)"; fi
|
|
rm -f "$PID_FILE"
|
|
else
|
|
echo "no pid file; nothing started by this script"
|
|
fi
|
|
}
|
|
|
|
mint_token() {
|
|
node -e '
|
|
const c=require("crypto");const s=process.env.JWT_SECRET;
|
|
if(!s){console.error("JWT_SECRET not set");process.exit(1);}
|
|
const b=o=>Buffer.from(JSON.stringify(o)).toString("base64url");
|
|
const h=b({alg:"HS256",typ:"JWT"});const n=Math.floor(Date.now()/1e3);
|
|
const p=b({sub:"gigafactory-deploy",email:"deploy@bytelyst.local",role:"admin",type:"access",iat:n,exp:n+3600});
|
|
console.log(`${h}.${p}.`+c.createHmac("sha256",s).update(`${h}.${p}`).digest("base64url"));
|
|
'
|
|
}
|
|
|
|
wait_for_health() {
|
|
echo -n "waiting for $BASE/health "
|
|
for _ in $(seq 1 60); do
|
|
if curl -fsS "$BASE/health" >/dev/null 2>&1; then echo "— ok"; return 0; fi
|
|
echo -n "."; sleep 1
|
|
done
|
|
echo; die "platform-service did not become healthy (see $LOG_FILE)"
|
|
}
|
|
|
|
register_products() {
|
|
local token; token="$(mint_token)"
|
|
local created=0 existed=0 failed=0
|
|
for tuple in $PRODUCTS; do
|
|
IFS='|' read -r id name prefix <<<"$tuple"
|
|
local code; code="$(curl -s -o /dev/null -w '%{http_code}' -X POST "$BASE/api/products" \
|
|
-H "Authorization: Bearer $token" -H "content-type: application/json" \
|
|
-H "x-product-id: $id" \
|
|
-d "{\"productId\":\"$id\",\"displayName\":\"$name\",\"licensePrefix\":\"$prefix\"}")"
|
|
case "$code" in
|
|
200|201) echo " created $id"; created=$((created+1));;
|
|
409) echo " exists $id"; existed=$((existed+1));;
|
|
*) echo " FAILED $id (HTTP $code)"; failed=$((failed+1));;
|
|
esac
|
|
done
|
|
echo "products: created=$created existed=$existed failed=$failed"
|
|
# live smoke: fleet metrics for the first product
|
|
local first; first="$(echo "$PRODUCTS" | awk '{print $1}' | cut -d'|' -f1)"
|
|
echo -n "smoke GET /api/fleet/metrics ($first): "
|
|
curl -s -H "Authorization: Bearer $(mint_token)" -H "x-product-id: $first" \
|
|
"$BASE/api/fleet/metrics" | head -c 200; echo
|
|
}
|
|
|
|
# ── main ─────────────────────────────────────────────────────────
|
|
case "${1:-}" in
|
|
--stop) stop_service; exit 0;;
|
|
esac
|
|
|
|
[ -n "$COMMON_PLAT" ] && [ -d "$PS_DIR" ] || die "platform-service not found (set COMMON_PLAT). Looked in: $PS_DIR"
|
|
[ -f "$ENV_FILE" ] || die "$ENV_FILE missing — fill it (Cosmos endpoint/key, JWT_SECRET, blob CS)"
|
|
set -a; . "$ENV_FILE"; set +a
|
|
|
|
if [ "${1:-}" != "--register-only" ]; then
|
|
if curl -fsS "$BASE/health" >/dev/null 2>&1; then
|
|
echo "platform-service already healthy on :$PORT — reusing it"
|
|
else
|
|
echo "starting platform-service on :$PORT (log: $LOG_FILE)"
|
|
( cd "$PS_DIR" && pnpm exec tsx src/server.ts >"$LOG_FILE" 2>&1 ) &
|
|
echo $! >"$PID_FILE"
|
|
wait_for_health
|
|
fi
|
|
fi
|
|
|
|
if [ "${1:-}" != "--no-register" ]; then
|
|
register_products
|
|
fi
|
|
|
|
cat <<EOF
|
|
|
|
Gigafactory is up on $BASE (health: $BASE/health)
|
|
Next:
|
|
- Run e2e: (cd "$COMMON_PLAT/dashboards/tracker-web" && pnpm exec playwright test)
|
|
- Stop: $HERE/$(basename "$0") --stop
|
|
EOF
|