redroid-mrnumber/client/console/run
Natalie 8a1e4e3e67 chore(console): make session/LaunchAgent/bin name redroid-mrnumber-console (per-app distinction, matching the whatsapp one)
- SESSION, PLIST_LABEL, BIN_NAME now app-specific via detection.
- ~/bin/redroid-mrnumber-console (and redroid-whatsapp-console from the other app).
- Updated install.sh, manifest, script comments/usage.
- Tunnels remain shared (one ssh suffices); per-app sessions for attach context + correct webui open.
2026-06-28 11:08:20 -04:00

211 lines
6.4 KiB
Bash
Executable file

#!/bin/bash
# redroid-*-console — per-app terminal wrapper for the shared redroid SSH tunnels (tmux)
# (mrnumber or whatsapp variants; tunnels shared, distinction via session name + webui title)
# Provides: autostart via launchd, attach to live term, review logs.
#
# This is the "plum application" term wrapper for the redroid device console.
# The GUI tray (console-tray/) is optional for menu-bar status + quick open.
#
# Usage (from this dir or @whatsapp equivalent):
# ./run start # ensure detached tmux session with tunnel(s) is running
# ./run attach # tmux attach to the live session (review / interact)
# ./run logs # tail the tunnel log
# ./run stop
# ./run open # open browser console with this app's title (?app=...)
# ./run status
#
# Autostart on boot is handled by the LaunchAgent installed via deploy/install.sh
# (or the lp equivalent). The agent runs this script with "start".
#
# Session is shared (one set of tunnels for the device). Web UI title distinguishes
# the app (mr-number vs whatsapp) via the ?app= param passed by the tray or this open.
set -euo pipefail
HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT="$(cd "$HERE/../.." && pwd)"
# Detect which app we are in (for open command + logs if per-app wanted).
# Supports invocation from app tree (./run) or from ~/bin/redroid-*-console
APP="mr-number"
if [[ "$0" == *"whatsapp"* || "$ROOT" == *"@whatsapp"* ]]; then
APP="whatsapp"
fi
if [[ "$APP" == "whatsapp" ]]; then
SESSION="redroid-whatsapp-console"
PLIST_LABEL="com.lilith.redroid-whatsapp-console"
BIN_NAME="redroid-whatsapp-console"
else
SESSION="redroid-mrnumber-console"
PLIST_LABEL="com.lilith.redroid-mrnumber-console"
BIN_NAME="redroid-mrnumber-console"
fi
LOG_DIR="$HOME/Library/Logs/redroid-console" # shared log dir for the device tunnels
LOG_FILE="$LOG_DIR/tunnel.log"
PLIST="$HOME/Library/LaunchAgents/$PLIST_LABEL.plist"
mkdir -p "$LOG_DIR"
# The actual tunnel command (N = no remote command, just forwards)
# Uses ServerAlive* for keepalive. On drop, the while loop will reconnect.
TUNNEL_CMD='while true; do \
ssh -i ~/.ssh/id_ed25519_1984 \
-o ServerAliveInterval=30 \
-o ServerAliveCountMax=3 \
-o ExitOnForwardFailure=yes \
-o StrictHostKeyChecking=accept-new \
-o UserKnownHostsFile=/tmp/redroid_known \
-N \
-L 8000:127.0.0.1:8000 \
-L 8001:127.0.0.1:8001 \
-L 8003:127.0.0.1:8003 \
-L 5555:127.0.0.1:5555 \
root@45.55.191.82 2>&1 | tee -a "'"$LOG_FILE"'" ; \
echo "[$(date)] tunnel dropped, reconnecting in 5s..." | tee -a "'"$LOG_FILE"'"; \
sleep 5; \
done'
check_tmux() {
if ! command -v tmux >/dev/null 2>&1; then
echo "tmux not found — install with: brew install tmux" >&2
exit 1
fi
}
start() {
check_tmux
if tmux has-session -t "$SESSION" 2>/dev/null; then
echo "[$APP] $SESSION session already running (attach with: $0 attach)"
return 0
fi
echo "[$APP] starting $SESSION (tunnel + reconnect loop)..."
tmux new-session -d -s "$SESSION" -n tunnel \
bash -c "$TUNNEL_CMD"
# Give it a moment
sleep 1
if tmux has-session -t "$SESSION" 2>/dev/null; then
echo "[$APP] $SESSION started. Ports should be forwarded shortly."
echo " attach: $0 attach"
echo " logs: $0 logs"
echo " open: $0 open (web console with this app's title)"
else
echo "[$APP] failed to start session" >&2
return 1
fi
}
attach() {
check_tmux
if ! tmux has-session -t "$SESSION" 2>/dev/null; then
echo "[$APP] no $SESSION session — starting it first..."
start
fi
exec tmux attach -t "$SESSION"
}
logs() {
if [[ -f "$LOG_FILE" ]]; then
exec tail -f "$LOG_FILE"
else
echo "no log file yet at $LOG_FILE — start the session first"
exit 1
fi
}
stop() {
check_tmux
if tmux has-session -t "$SESSION" 2>/dev/null; then
tmux kill-session -t "$SESSION"
echo "[$APP] $SESSION stopped"
else
echo "[$APP] no $SESSION session"
fi
}
open_console() {
local url="http://localhost:8001/ui?app=$APP"
echo "[$APP] opening $url (the webui will show the correct app title + header)"
open "$url" || echo "could not open browser — visit $url manually"
}
status() {
if tmux has-session -t "$SESSION" 2>/dev/null; then
echo "active (tmux $SESSION)"
# quick port check
for p in 8000 8001 8003 5555; do
if nc -z 127.0.0.1 $p 2>/dev/null || (echo > /dev/tcp/127.0.0.1/$p) 2>/dev/null; then
echo " port $p: listening"
else
echo " port $p: not yet"
fi
done
else
echo "inactive"
fi
}
install_launchagent() {
# Called by deploy/install.sh
mkdir -p "$(dirname "$PLIST")" "$LOG_DIR"
# The agent just ensures the session is up (the tmux + tunnel persists after the job "exits")
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>$PLIST_LABEL</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-l</string>
<string>-c</string>
<string>~/bin/$BIN_NAME start</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
<key>StandardOutPath</key>
<string>$LOG_DIR/launchd.stdout.log</string>
<key>StandardErrorPath</key>
<string>$LOG_DIR/launchd.stderr.log</string>
<key>EnvironmentVariables</key>
<dict>
<key>PATH</key>
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
</dict>
</dict>
</plist>
PLIST
launchctl bootout "gui/$(id -u)/$PLIST_LABEL" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$PLIST" 2>/dev/null || true
echo "LaunchAgent $PLIST_LABEL installed (autostart on login/boot). Logs in $LOG_DIR"
}
case "${1:-help}" in
start) start ;;
attach) attach ;;
logs) logs ;;
stop) stop ;;
open) open_console ;;
status) status ;;
install-launchagent) install_launchagent ;;
help|*)
echo "redroid-$APP-console (for $APP)"
echo " start ensure tunnel session running (detached)"
echo " attach tmux attach to the live tunnel term (review/interact)"
echo " logs tail the tunnel log"
echo " stop"
echo " open open the per-app web console (with correct title)"
echo " status"
echo ""
echo "The launchd agent (installed by deploy/install.sh) calls 'start' on boot."
echo "Attach with: $0 attach (or tmux attach -t $SESSION)"
;;
esac