110 lines
2.8 KiB
Bash
Executable File
110 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Portable AetherForge / forge-mesh command deck launcher (USB edition).
|
|
# Starts optional cloudflared sidecar, sets AF_TUNNEL_EXTERNAL=1, opens the deck UI,
|
|
# and runs forge-mesh-server against ./data.
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
if [[ "$(basename "$SCRIPT_DIR")" == "scripts" ]]; then
|
|
ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
else
|
|
ROOT="$SCRIPT_DIR"
|
|
fi
|
|
cd "$ROOT"
|
|
|
|
DATA_DIR="${AF_DATA_DIR:-$ROOT/data}"
|
|
CONFIG="${AF_CONFIG:-$DATA_DIR/config.json}"
|
|
SERVER_BIN="${AF_SERVER_BIN:-$ROOT/bin/forge-mesh-server}"
|
|
DECK_URL="${AF_DECK_URL:-http://localhost:8989}"
|
|
CLOUDFLARED_PID=""
|
|
|
|
cleanup() {
|
|
if [[ -n "$CLOUDFLARED_PID" ]] && kill -0 "$CLOUDFLARED_PID" 2>/dev/null; then
|
|
kill "$CLOUDFLARED_PID" 2>/dev/null || true
|
|
wait "$CLOUDFLARED_PID" 2>/dev/null || true
|
|
fi
|
|
}
|
|
trap cleanup EXIT INT TERM
|
|
|
|
resolve_cloudflared() {
|
|
if command -v cloudflared >/dev/null 2>&1; then
|
|
command -v cloudflared
|
|
return 0
|
|
fi
|
|
for candidate in "$ROOT/bin/cloudflared" "$ROOT/cloudflared"; do
|
|
if [[ -x "$candidate" ]]; then
|
|
echo "$candidate"
|
|
return 0
|
|
fi
|
|
done
|
|
return 1
|
|
}
|
|
|
|
read_tunnel_token() {
|
|
if [[ -n "${AF_TUNNEL_TOKEN:-}" ]]; then
|
|
printf '%s' "$AF_TUNNEL_TOKEN"
|
|
return 0
|
|
fi
|
|
local token_file="$DATA_DIR/cloudflared-token.txt"
|
|
if [[ -f "$token_file" ]]; then
|
|
tr -d '[:space:]' <"$token_file"
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
start_tunnel_sidecar() {
|
|
local token cf_bin
|
|
token="$(read_tunnel_token)" || return 0
|
|
cf_bin="$(resolve_cloudflared)" || {
|
|
echo "WARN: tunnel token present but cloudflared not found (PATH or $ROOT/bin/cloudflared)" >&2
|
|
return 0
|
|
}
|
|
|
|
echo "Starting cloudflared sidecar..."
|
|
"$cf_bin" tunnel --no-autoupdate run --token "$token" &
|
|
CLOUDFLARED_PID=$!
|
|
export AF_TUNNEL_EXTERNAL=1
|
|
echo "AF_TUNNEL_EXTERNAL=1 (cloudflared pid $CLOUDFLARED_PID)"
|
|
}
|
|
|
|
open_browser() {
|
|
local url="$1"
|
|
if [[ -n "${AF_NO_BROWSER:-}" ]]; then
|
|
echo "AF_NO_BROWSER set; deck at $url"
|
|
return 0
|
|
fi
|
|
for opener in xdg-open sensible-browser x-www-browser gnome-open kde-open; do
|
|
if command -v "$opener" >/dev/null 2>&1; then
|
|
"$opener" "$url" >/dev/null 2>&1 &
|
|
return 0
|
|
fi
|
|
done
|
|
echo "Open your browser to $url"
|
|
}
|
|
|
|
ensure_server_binary() {
|
|
if [[ -x "$SERVER_BIN" ]]; then
|
|
return 0
|
|
fi
|
|
if command -v forge-mesh-server >/dev/null 2>&1; then
|
|
SERVER_BIN="$(command -v forge-mesh-server)"
|
|
return 0
|
|
fi
|
|
echo "ERROR: forge-mesh-server not found. Build with 'make server' or place binary in $ROOT/bin/" >&2
|
|
exit 1
|
|
}
|
|
|
|
mkdir -p "$DATA_DIR"
|
|
if [[ ! -f "$CONFIG" ]]; then
|
|
echo "ERROR: missing config at $CONFIG" >&2
|
|
exit 1
|
|
fi
|
|
|
|
start_tunnel_sidecar
|
|
ensure_server_binary
|
|
|
|
open_browser "$DECK_URL"
|
|
echo "Starting forge-mesh-server (config: $CONFIG)"
|
|
exec "$SERVER_BIN" -config "$CONFIG"
|