Files
openswarm/backend/apps/outputs/webapp_template/run.sh
T

112 lines
3.8 KiB
Bash
Executable File

#!/bin/bash
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
if [[ -f "$ROOT_DIR/.env" ]]; then
set -a
source "$ROOT_DIR/.env"
set +a
fi
# Recursively SIGTERM a pid + all of its descendants. We track FRONTEND_PID
# and BACKEND_PID below, but each of those is a `bash` wrapper that has its
# own grandchildren (vite, uvicorn, npm). A flat `kill $FRONTEND_PID` leaves
# the grandchildren alive holding their ports until the OS reaps them
# minutes later — visible to the user as port-already-in-use the next time
# they hit the App Builder.
kill_tree() {
local pid=$1 sig=${2:-TERM}
local children
children=$(pgrep -P "$pid" 2>/dev/null)
for child in $children; do
kill_tree "$child" "$sig"
done
kill -"$sig" "$pid" 2>/dev/null
}
# Previously this was `kill 0`, which SIGTERMs the entire process group.
# That's fast but propagates UP into OpenSwarm — when this workspace's
# cleanup fired on ViewEditor unmount or runtime/stop, it tore down the
# OpenSwarm dev stack (Terminated: 15) and left port 8324 stuck. Now we
# only kill our own tracked subtree, which keeps containment without
# requiring an OS-level session wall.
cleanup() {
echo ""
echo "Shutting down all processes..."
[[ -n "${FRONTEND_PID:-}" ]] && kill_tree "$FRONTEND_PID" TERM
[[ -n "${BACKEND_PID:-}" ]] && kill_tree "$BACKEND_PID" TERM
wait 2>/dev/null
}
trap cleanup EXIT
if [[ "${BACKEND_PORT}" == "NONE" || -z "${BACKEND_PORT}" || ! -f "$ROOT_DIR/backend/run.sh" ]]; then
# Frontend-only is the safe default: BACKEND_PORT=NONE (frontend-only app),
# OR unset/empty (e.g. .env missing — never start a backend that isn't
# configured), OR there is genuinely no backend/run.sh to run. Without the
# last two guards an unset BACKEND_PORT fell through to the backend branch
# and `bash backend/run.sh` died with "No such file or directory", tearing
# the whole app down before the frontend could show.
echo "Running frontend only (no backend configured)."
echo ""
bash "$ROOT_DIR/frontend/run.sh" 2>&1 | awk '{printf "\033[32m[frontend]\033[0m %s\n", $0; fflush()}' &
FRONTEND_PID=$!
while true; do
if ! kill -0 $FRONTEND_PID 2>/dev/null; then
echo ""
echo "ERROR: Frontend process exited. Tearing down..."
exit 1
fi
sleep 2
done
else
BACKEND_URL="http://localhost:${BACKEND_PORT:-8324}/api/health/check"
MAX_WAIT=60
echo "Starting backend..."
echo ""
bash "$ROOT_DIR/backend/run.sh" 2>&1 | awk '{printf "\033[34m[backend]\033[0m %s\n", $0; fflush()}' &
BACKEND_PID=$!
echo "Waiting for backend to be ready..."
elapsed=0
while [ $elapsed -lt $MAX_WAIT ]; do
if ! kill -0 $BACKEND_PID 2>/dev/null; then
echo "ERROR: Backend process died before becoming ready. Aborting."
exit 1
fi
if curl -s -o /dev/null -w "%{http_code}" "$BACKEND_URL" 2>/dev/null | grep -q "200"; then
echo ""
echo "Backend is ready! Starting frontend..."
echo ""
break
fi
sleep 1
elapsed=$((elapsed + 1))
done
if [ $elapsed -ge $MAX_WAIT ]; then
echo "ERROR: Backend failed to start within ${MAX_WAIT}s. Aborting."
exit 1
fi
bash "$ROOT_DIR/frontend/run.sh" 2>&1 | awk '{printf "\033[32m[frontend]\033[0m %s\n", $0; fflush()}' &
FRONTEND_PID=$!
while true; do
if ! kill -0 $BACKEND_PID 2>/dev/null; then
echo ""
echo "ERROR: Backend process exited. Tearing down..."
exit 1
fi
if ! kill -0 $FRONTEND_PID 2>/dev/null; then
echo ""
echo "ERROR: Frontend process exited. Tearing down..."
exit 1
fi
sleep 2
done
fi