-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdev.sh
More file actions
executable file
·178 lines (151 loc) · 4.98 KB
/
dev.sh
File metadata and controls
executable file
·178 lines (151 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/usr/bin/env bash
# Unified dev runner for backend (FastAPI) + frontend (Vite)
set -euo pipefail
ROOT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
API_PORT="${API_PORT:-5179}"
API_HOST="${API_HOST:-127.0.0.1}"
WEB_PORT="${WEB_PORT:-5173}"
DEFAULT_SCHEMA_REPO="${HOME}/src/nomad-simulations"
UVICORN_LOG_LEVEL="${UVICORN_LOG_LEVEL:-warning}"
# Dev-friendly auth defaults (override via env for non-dev)
: "${SCHEMA_UML_ALLOW_INSECURE_DEFAULTS:=true}"
: "${SCHEMA_UML_ENABLE_DEFAULT_ADMIN:=true}"
: "${SCHEMA_UML_DEFAULT_USER:=admin}"
: "${SCHEMA_UML_DEFAULT_PASSWORD:=admin}"
: "${SCHEMA_UML_SECRET:=dev-secret}"
: "${SCHEMA_UML_PW_SALT:=dev-salt}"
: "${SCHEMA_UML_MONGO_URI:=mongodb://localhost:27017}"
: "${SCHEMA_UML_MONGO_DB:=schema_uml}"
# Set START_MONGO_DOCKER=1 to have this script start a local MongoDB container (mongo:7)
need_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "Error: '$1' not found. Please install it (or activate your virtualenv) and retry." >&2
exit 1
fi
}
need_cmd git
need_cmd uvicorn
need_cmd npm
start_mongo_docker() {
if [[ -z "${START_MONGO_DOCKER:-}" ]]; then
return
fi
need_cmd docker
if docker ps --format '{{.Names}}' | grep -q '^schema-uml-mongo$'; then
echo "MongoDB container 'schema-uml-mongo' is already running."
return
fi
echo "Starting MongoDB container 'schema-uml-mongo'..."
docker rm -f schema-uml-mongo >/dev/null 2>&1 || true
if ! docker run --name schema-uml-mongo -p 27017:27017 -v /tmp/mongo-data:/data/db -d mongo:7 >/dev/null; then
echo "Failed to start MongoDB 7 (mongo:7) container. Start Mongo manually or check Docker permissions."
exit 1
fi
}
# Verify required Python packages are installed before starting uvicorn.
python - <<'PY'
try:
import jwt # PyJWT
except ModuleNotFoundError:
import sys
sys.stderr.write(
"Missing dependency: PyJWT is required.\n"
"Install backend requirements via `pip install -r api/requirements.txt` and retry.\n"
)
sys.exit(1)
PY
resolve_schema_repo() {
# Mirrors api/settings.py resolution order
local candidate
for var in SCHEMA_UML_REPO NOMAD_SIM_REPO GIT_REPO_DIR; do
candidate=${!var-}
if [[ -n "${candidate}" ]]; then
echo "${candidate}"
return 0
fi
done
echo "${DEFAULT_SCHEMA_REPO}"
}
validate_schema_repo() {
local repo_path
repo_path="$(resolve_schema_repo)"
if [[ ! -d "${repo_path}" ]]; then
cat <<EOF
Error: Could not find a schema repository.
- Set one of SCHEMA_UML_REPO / NOMAD_SIM_REPO / GIT_REPO_DIR to a local git clone.
- Current default (${DEFAULT_SCHEMA_REPO}) does not exist.
EOF
exit 1
fi
if ! git -C "${repo_path}" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
cat <<EOF
Error: '${repo_path}' is not a git repository.
- Point SCHEMA_UML_REPO (or NOMAD_SIM_REPO / GIT_REPO_DIR) to a local clone (a subdirectory of a clone is fine).
EOF
exit 1
fi
echo "Using schema repo: ${repo_path}"
}
cleanup() {
trap - EXIT INT TERM
for pid in "${API_PID:-}" "${WEB_PID:-}"; do
if [[ -n "${pid}" ]] && ps -p "${pid}" > /dev/null 2>&1; then
kill "${pid}" 2>/dev/null || true
fi
done
}
trap cleanup EXIT INT TERM
cd "${ROOT_DIR}"
validate_schema_repo
start_mongo_docker
echo "Checking MongoDB at ${SCHEMA_UML_MONGO_URI}/${SCHEMA_UML_MONGO_DB}..."
python - <<'PY'
import os, sys, asyncio
from motor.motor_asyncio import AsyncIOMotorClient
uri = os.getenv("SCHEMA_UML_MONGO_URI", "mongodb://localhost:27017")
async def main():
client = AsyncIOMotorClient(uri, serverSelectionTimeoutMS=10000)
try:
await client.admin.command("ping")
client.close()
return True
except Exception as exc: # pragma: no cover
sys.stderr.write(f"MongoDB not reachable at {uri}: {exc}\n")
client.close()
return False
ok = asyncio.run(main())
if not ok:
sys.exit(1)
PY
echo "Starting FastAPI backend on :${API_PORT}..."
uvicorn --app-dir "${ROOT_DIR}" api.main:app --reload --host "${API_HOST}" --port "${API_PORT}" --log-level "${UVICORN_LOG_LEVEL}" &
API_PID=$!
echo "Switching to frontend (web/)"
cd "${ROOT_DIR}/web"
if [[ ! -d node_modules ]]; then
echo "Installing frontend dependencies (web/node_modules not found)..."
npm install
fi
echo "Starting Vite frontend on :${WEB_PORT}..."
npm run dev -- --host --port "${WEB_PORT}" &
WEB_PID=$!
cd "${ROOT_DIR}"
echo "Both services launched. Press Ctrl+C to stop."
# Wait until one of the services exits (or the user hits Ctrl+C). macOS ships with
# Bash 3.x, which lacks `wait -n`, so poll the processes for portability.
status_api=""
status_web=""
while true; do
if [[ -z "${status_api}" ]] && ! ps -p "${API_PID}" >/dev/null 2>&1; then
wait "${API_PID}" || status_api=$?
break
fi
if [[ -z "${status_web}" ]] && ! ps -p "${WEB_PID}" >/dev/null 2>&1; then
wait "${WEB_PID}" || status_web=$?
break
fi
sleep 1
done
if [[ -n "${status_api}" || -n "${status_web}" ]]; then
echo "A service stopped with a non-zero exit code. Shutting down the stack..."
fi