84 lines
2.5 KiB
Bash
Executable File
84 lines
2.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
LABEL="local.nodedc.launcher-bff"
|
|
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
NODE_BIN="${NODE_BIN:-$(command -v node)}"
|
|
LOG_OUT="/tmp/nodedc-launcher-bff.out.log"
|
|
LOG_ERR="/tmp/nodedc-launcher-bff.err.log"
|
|
USER_ID="$(id -u)"
|
|
|
|
if [[ -z "${NODE_BIN}" || ! -x "${NODE_BIN}" ]]; then
|
|
echo "Node.js executable not found. Set NODE_BIN=/absolute/path/to/node and retry." >&2
|
|
exit 1
|
|
fi
|
|
|
|
mkdir -p "$(dirname "${PLIST}")"
|
|
|
|
launchctl bootout "gui/${USER_ID}/${LABEL}" >/dev/null 2>&1 || true
|
|
launchctl bootout "gui/${USER_ID}" "${PLIST}" >/dev/null 2>&1 || true
|
|
|
|
if command -v lsof >/dev/null 2>&1; then
|
|
while IFS= read -r PID_ON_PORT; do
|
|
[[ -z "${PID_ON_PORT}" ]] && continue
|
|
COMMAND_LINE="$(ps -p "${PID_ON_PORT}" -o command= 2>/dev/null || true)"
|
|
if [[ "${COMMAND_LINE}" == *"server/dev-server.mjs"* ]]; then
|
|
kill "${PID_ON_PORT}" >/dev/null 2>&1 || true
|
|
fi
|
|
done < <(lsof -tiTCP:5173 -sTCP:LISTEN 2>/dev/null || true)
|
|
fi
|
|
|
|
cat > "${PLIST}" <<PLIST
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
<plist version="1.0">
|
|
<dict>
|
|
<key>Label</key>
|
|
<string>${LABEL}</string>
|
|
<key>ProgramArguments</key>
|
|
<array>
|
|
<string>${NODE_BIN}</string>
|
|
<string>${REPO_DIR}/server/dev-server.mjs</string>
|
|
</array>
|
|
<key>WorkingDirectory</key>
|
|
<string>${REPO_DIR}</string>
|
|
<key>RunAtLoad</key>
|
|
<true/>
|
|
<key>KeepAlive</key>
|
|
<dict>
|
|
<key>SuccessfulExit</key>
|
|
<false/>
|
|
</dict>
|
|
<key>EnvironmentVariables</key>
|
|
<dict>
|
|
<key>PATH</key>
|
|
<string>$(dirname "${NODE_BIN}"):/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin</string>
|
|
</dict>
|
|
<key>StandardOutPath</key>
|
|
<string>${LOG_OUT}</string>
|
|
<key>StandardErrorPath</key>
|
|
<string>${LOG_ERR}</string>
|
|
</dict>
|
|
</plist>
|
|
PLIST
|
|
|
|
launchctl bootstrap "gui/${USER_ID}" "${PLIST}"
|
|
launchctl enable "gui/${USER_ID}/${LABEL}" >/dev/null 2>&1 || true
|
|
launchctl kickstart -k "gui/${USER_ID}/${LABEL}" >/dev/null 2>&1 || true
|
|
|
|
for _ in {1..20}; do
|
|
if curl -fsS --max-time 2 http://launcher.local.nodedc/healthz >/dev/null 2>&1; then
|
|
echo "NODE.DC launcher BFF is running via LaunchAgent: ${LABEL}"
|
|
echo "Health: http://launcher.local.nodedc/healthz"
|
|
echo "Logs: ${LOG_OUT} / ${LOG_ERR}"
|
|
exit 0
|
|
fi
|
|
sleep 0.5
|
|
done
|
|
|
|
echo "LaunchAgent installed, but health check failed." >&2
|
|
echo "Check logs: ${LOG_OUT} / ${LOG_ERR}" >&2
|
|
exit 1
|