feat: entrypoint.sh starting all services
This commit is contained in:
Executable
+52
@@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export DISPLAY=:99
|
||||||
|
|
||||||
|
echo "=== Starting Research Workbench ==="
|
||||||
|
|
||||||
|
# (1) Start Xvfb
|
||||||
|
Xvfb :99 -screen 0 1280x720x24 -ac &
|
||||||
|
sleep 1
|
||||||
|
echo "[OK] Xvfb display :99"
|
||||||
|
|
||||||
|
# (2) Start x11vnc (suppress stderr)
|
||||||
|
x11vnc -display :99 -forever -nopw -listen 0.0.0.0 -rfbport 5900 -shared 2>/dev/null &
|
||||||
|
sleep 1
|
||||||
|
echo "[OK] x11vnc on :5900"
|
||||||
|
|
||||||
|
# (3) Start noVNC via websockify
|
||||||
|
websockify --web=/usr/share/novnc/ 6080 localhost:5900 &
|
||||||
|
sleep 1
|
||||||
|
echo "[OK] noVNC on :6080"
|
||||||
|
|
||||||
|
# (4) Start amplifierd and wait for it to be healthy
|
||||||
|
cd /app
|
||||||
|
amplifierd --port 8410 --bundle /app/bundle/bundle.md &
|
||||||
|
AMPLIFIERD_PID=$!
|
||||||
|
|
||||||
|
echo "Waiting for amplifierd..."
|
||||||
|
for i in $(seq 1 30); do
|
||||||
|
if curl -s http://localhost:8410/health > /dev/null 2>&1; then
|
||||||
|
echo "[OK] amplifierd on :8410"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# (5) Start FastAPI backend
|
||||||
|
cd /app/backend
|
||||||
|
uv run python -m uvicorn app:app --host 0.0.0.0 --port 8080 --log-level info &
|
||||||
|
sleep 2
|
||||||
|
echo "[OK] FastAPI on :8080"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Research Workbench: http://localhost:8080"
|
||||||
|
echo "Browser VNC: http://localhost:6080"
|
||||||
|
|
||||||
|
# CMD passthrough or wait on amplifierd
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
wait $AMPLIFIERD_PID
|
||||||
|
else
|
||||||
|
exec "$@"
|
||||||
|
fi
|
||||||
Executable
+134
@@ -0,0 +1,134 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# test_entrypoint.sh - Verify entrypoint.sh matches spec for task-8-entrypoint-script
|
||||||
|
# RED: Run before entrypoint.sh exists (should fail)
|
||||||
|
# GREEN: Run after entrypoint.sh is created (should pass)
|
||||||
|
|
||||||
|
REPO=/home/ken/workspace/research-workbench
|
||||||
|
ENTRYPOINT="$REPO/entrypoint.sh"
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
check_file() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "PASS: file '$1' exists"
|
||||||
|
((PASS++))
|
||||||
|
else
|
||||||
|
echo "FAIL: file '$1' should exist but is missing"
|
||||||
|
((FAIL++))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_executable() {
|
||||||
|
if [ -x "$1" ]; then
|
||||||
|
echo "PASS: '$1' is executable"
|
||||||
|
((PASS++))
|
||||||
|
else
|
||||||
|
echo "FAIL: '$1' should be executable"
|
||||||
|
((FAIL++))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_contains() {
|
||||||
|
local pattern="$1"
|
||||||
|
local label="$2"
|
||||||
|
if grep -qF -- "$pattern" "$ENTRYPOINT" 2>/dev/null; then
|
||||||
|
echo "PASS: entrypoint.sh contains $label"
|
||||||
|
((PASS++))
|
||||||
|
else
|
||||||
|
echo "FAIL: entrypoint.sh missing $label"
|
||||||
|
((FAIL++))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_regex() {
|
||||||
|
local pattern="$1"
|
||||||
|
local label="$2"
|
||||||
|
if grep -qE "$pattern" "$ENTRYPOINT" 2>/dev/null; then
|
||||||
|
echo "PASS: entrypoint.sh contains $label"
|
||||||
|
((PASS++))
|
||||||
|
else
|
||||||
|
echo "FAIL: entrypoint.sh missing $label"
|
||||||
|
((FAIL++))
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "=== Checking entrypoint.sh exists ==="
|
||||||
|
check_file "$ENTRYPOINT"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking shebang and shell settings ==="
|
||||||
|
check_regex "^#!/bin/bash" "bash shebang"
|
||||||
|
check_contains "set -e" "set -e"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking DISPLAY export ==="
|
||||||
|
check_contains "export DISPLAY=:99" "export DISPLAY=:99"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking startup banner ==="
|
||||||
|
check_contains "=== Starting Research Workbench ===" "startup banner"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking Xvfb startup ==="
|
||||||
|
check_contains "Xvfb :99 -screen 0 1280x720x24 -ac" "Xvfb command"
|
||||||
|
check_regex "Xvfb.*&" "Xvfb in background"
|
||||||
|
check_contains "[OK] Xvfb display :99" "[OK] Xvfb message"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking x11vnc startup ==="
|
||||||
|
check_contains "x11vnc -display :99 -forever -nopw -listen 0.0.0.0 -rfbport 5900 -shared" "x11vnc command"
|
||||||
|
check_regex "x11vnc.*&" "x11vnc in background"
|
||||||
|
check_contains "[OK] x11vnc on :5900" "[OK] x11vnc message"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking noVNC/websockify startup ==="
|
||||||
|
check_regex "websockify.*--web.*6080.*5900" "websockify command"
|
||||||
|
check_regex "websockify.*&" "websockify in background"
|
||||||
|
check_contains "[OK] noVNC on :6080" "[OK] noVNC message"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking amplifierd startup ==="
|
||||||
|
check_regex "cd /app" "cd /app"
|
||||||
|
check_contains "amplifierd --port 8410 --bundle /app/bundle/bundle.md" "amplifierd command"
|
||||||
|
check_regex "amplifierd.*&" "amplifierd in background"
|
||||||
|
check_contains "AMPLIFIERD_PID" "AMPLIFIERD_PID variable"
|
||||||
|
check_regex "AMPLIFIERD_PID=\\\$!" "AMPLIFIERD_PID=\$!"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking amplifierd health-check wait loop ==="
|
||||||
|
check_regex "for|while" "loop construct"
|
||||||
|
check_contains "curl -s http://localhost:8410/health" "health check curl"
|
||||||
|
check_regex "30" "30 second timeout"
|
||||||
|
check_contains "[OK] amplifierd on :8410" "[OK] amplifierd message"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking FastAPI startup ==="
|
||||||
|
check_regex "cd /app/backend" "cd /app/backend"
|
||||||
|
check_contains "uv run python -m uvicorn app:app --host 0.0.0.0 --port 8080 --log-level info" "uvicorn command"
|
||||||
|
check_regex "uvicorn.*&" "uvicorn in background"
|
||||||
|
check_contains "[OK] FastAPI on :8080" "[OK] FastAPI message"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking final banner ==="
|
||||||
|
check_contains "Research Workbench" "Research Workbench banner"
|
||||||
|
check_contains "http://localhost:8080" "FastAPI URL in banner"
|
||||||
|
check_contains "http://localhost:6080" "noVNC URL in banner"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking CMD passthrough ==="
|
||||||
|
check_regex 'exec "\$@"' 'exec "$@" for CMD passthrough'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking wait on AMPLIFIERD_PID ==="
|
||||||
|
check_regex 'wait \$AMPLIFIERD_PID' 'wait $AMPLIFIERD_PID'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== Checking conditional logic (no args → wait, args → exec) ==="
|
||||||
|
check_regex '\$#' 'argument count check'
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=============================="
|
||||||
|
echo "Results: $PASS passed, $FAIL failed"
|
||||||
|
echo "=============================="
|
||||||
|
|
||||||
|
[ $FAIL -eq 0 ] && exit 0 || exit 1
|
||||||
Reference in New Issue
Block a user