-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstart.sh
More file actions
185 lines (170 loc) · 8.56 KB
/
start.sh
File metadata and controls
185 lines (170 loc) · 8.56 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
179
180
181
182
183
184
185
#!/bin/bash
# Brave Origin Nightly start — launches Xtigervnc, openbox, Brave, the control
# sidecar, and websockify (which bridges HTTP+WebSocket on 9611 → RFB on 5901).
# Every service's output is redirected to its own file in /root/.vnc/ so the
# app's Logs tab (served by control.py) can show everything that's happening.
mkdir -p /root/.vnc /opt/brave-ui /run
# Start-script output itself goes to start.log so the Logs tab sees boot steps.
exec > >(tee -a /root/.vnc/start.log) 2>&1
echo
echo "[brave/start] === $(date -Iseconds) ==="
# Belt-and-suspenders cleanup of anything left behind from a previous run.
pkill -9 Xtigervnc openbox brave 2>/dev/null || true
fuser -k 9611/tcp 5901/tcp 9612/tcp 2>/dev/null || true
sleep 1
# Recursive-mirror guard: block loopback traffic to the UI ports. The Windows
# webview reaches us through the WSL VM's external NIC (172.30.x.x), so it's
# unaffected — but anything *inside* the distro (Brave's address bar, curl,
# random process) trying http://localhost:9611 gets connection-refused and
# can't trigger the "camera-pointed-at-a-TV" feedback loop where Brave renders
# a view of its own display. iptables stderr is captured so an iptables-legacy
# vs iptables-nft mismatch shows up in start.log instead of silently disabling
# the guard.
if command -v iptables >/dev/null 2>&1; then
iptables -D INPUT -i lo -p tcp --dport 9611 -j REJECT 2>/dev/null || true
iptables -D INPUT -i lo -p tcp --dport 9612 -j REJECT 2>/dev/null || true
ipt_err=$( { iptables -I INPUT -i lo -p tcp --dport 9611 -j REJECT && \
iptables -I INPUT -i lo -p tcp --dport 9612 -j REJECT; } 2>&1 )
ipt_rc=$?
if [ $ipt_rc -eq 0 ]; then
echo "[brave/start] blocked lo -> 9611/9612 (mirror guard active)"
else
echo "[brave/start] WARNING: iptables rule install failed (exit $ipt_rc) — mirror guard INACTIVE"
[ -n "$ipt_err" ] && echo "[brave/start] iptables said: $ipt_err"
fi
else
echo "[brave/start] WARNING: iptables not installed — mirror guard inactive"
fi
# Fresh per-run service logs (but keep setup.log + update.log, which accumulate
# across runs — the user wants historical context for installs/updates).
rm -f /root/.vnc/Xtigervnc.log /root/.vnc/openbox.log /root/.vnc/brave.log \
/root/.vnc/websockify.log /root/.vnc/control.log \
/root/.vnc/*.pid /tmp/.X1-lock
# Save our PID so stop.sh can walk the process tree from here. After the final
# `exec websockify`, this PID is websockify itself — every service we've
# launched is a descendant of it, so kill_tree from this PID catches them all.
echo $$ > /run/brave.pid
echo "[brave/start] pid=$$"
# Pull the fresh UI wrapper (iframe + tabs + banner) from the app folder so
# the author can edit index.html on disk and see changes on next start without
# re-running setup.sh.
cp /opt/app/index.html /opt/brave-ui/index.html
echo "[brave/start] UI wrapper staged at /opt/brave-ui/index.html"
# WSLg bind-mounts /tmp/.X11-unix read-only, so Xtigervnc's default unix socket
# creation fails ("Mode of /tmp/.X11-unix should be set to 1777"). -nolisten
# unix skips socket creation entirely; the server listens only on TCP :5901.
echo "[brave/start] launching Xtigervnc :1"
Xtigervnc :1 \
-geometry 1100x750 \
-depth 24 \
-SecurityTypes None \
-localhost yes \
-desktop Brave \
-nolisten unix \
> /root/.vnc/Xtigervnc.log 2>&1 &
sleep 2
# Hard-fail if Xtigervnc didn't come up — otherwise openbox/brave/websockify
# would all cheerfully launch against a dead display and we'd print
# "ALL SERVICES UP" while the user sees a blank noVNC disconnect screen.
if ! pgrep -x Xtigervnc >/dev/null 2>&1; then
echo "[brave/start] FATAL: Xtigervnc did not start"
echo "[brave/start] --- last 20 lines of /root/.vnc/Xtigervnc.log ---"
tail -20 /root/.vnc/Xtigervnc.log 2>/dev/null || echo "[brave/start] (log missing)"
exit 1
fi
echo "[brave/start] launching openbox"
DISPLAY=:1 openbox > /root/.vnc/openbox.log 2>&1 &
sleep 1
# Scrub Brave's session + cache state so it can't mirror itself.
#
# Three separate things have to be cleared:
#
# 1. Session files (Current/Last Session/Tabs + Sessions/) — these hold the
# URL list the last tab had open. Deleting them kills the "Restore pages?"
# bubble and prevents the crashed-session restore path.
#
# 2. Preferences.session.restore_on_startup — this is what Chrome actually
# reads to decide whether to reopen last-session URLs on startup,
# independently of the Session files. Set to 5 = "open New Tab page".
# Without this, even a cleared Session will still try to load whatever
# URL the user last visited via Chrome's "Continue where you left off"
# feature.
#
# 3. Cache + Code Cache + GPUCache — Chrome's disk cache will serve a
# stale copy of http://localhost:9611/ even after iptables starts
# rejecting connections, which is exactly how the recursive mirror came
# back: the HTML loads from cache, the JS iframe tries a brand-new
# WebSocket (uncacheable) which hits the firewall, and we end up with
# two layers of UI stacked on top of each other. Wipe the cache and the
# cached mirror content is gone.
BRAVE_PROFILE=/root/brave-data/Default
if [ -d "$BRAVE_PROFILE" ]; then
rm -f "$BRAVE_PROFILE"/Current\ Session "$BRAVE_PROFILE"/Current\ Tabs \
"$BRAVE_PROFILE"/Last\ Session "$BRAVE_PROFILE"/Last\ Tabs
rm -rf "$BRAVE_PROFILE/Sessions" \
"$BRAVE_PROFILE/Cache" \
"$BRAVE_PROFILE/Code Cache" \
"$BRAVE_PROFILE/GPUCache"
if [ -f "$BRAVE_PROFILE/Preferences" ]; then
python3 - "$BRAVE_PROFILE/Preferences" <<'PYEOF' 2>/dev/null || true
import json, sys
p = sys.argv[1]
with open(p) as f: d = json.load(f)
d.setdefault("profile", {})["exit_type"] = "Normal"
d["profile"]["exited_cleanly"] = True
d.setdefault("session", {})["restore_on_startup"] = 5 # 5 = always open NTP
d["session"]["startup_urls"] = []
d["session"]["urls_to_restore_on_startup"] = []
with open(p, "w") as f: json.dump(d, f)
PYEOF
fi
echo "[brave/start] scrubbed Brave session + cache state"
fi
# Brave flags:
# --no-sandbox: user-namespace sandbox needs CAP_SYS_ADMIN (not in WSL2)
# --disable-gpu: no hw GL inside Xvnc
# --disable-dev-shm-usage: WSL2's /dev/shm is small — can crash renderers
# --test-type: suppresses the yellow "unsupported command-line flag" infobar
# --disable-session-crashed-bubble: extra belt for the "Restore pages?" prompt
# --no-default-browser-check / --no-first-run: skip onboarding noise
echo "[brave/start] launching brave-origin-nightly"
DISPLAY=:1 brave-origin-nightly \
--no-sandbox \
--test-type \
--no-first-run \
--no-default-browser-check \
--disable-session-crashed-bubble \
--disable-gpu \
--disable-dev-shm-usage \
--disable-features=UseOzonePlatform \
--start-maximized \
--user-data-dir=/root/brave-data \
> /root/.vnc/brave.log 2>&1 &
sleep 2
# Control sidecar — /api/shutdown, /api/update, /api/logs, /api/settings.
# Binds 0.0.0.0:9612 so Windows-side WebView2 can reach it via WSL localhost
# forwarding (see control.py header).
echo "[brave/start] launching control sidecar on 9612"
python3 /opt/app/control.py 9612 > /root/.vnc/control.log 2>&1 &
sleep 1
echo "[brave/start] ========================================"
echo "[brave/start] ALL SERVICES UP — BRAVE IS LIVE"
echo "[brave/start] Xtigervnc (display :1, RFB 5901)"
echo "[brave/start] openbox (window manager)"
echo "[brave/start] brave-origin-nightly (on display :1)"
echo "[brave/start] control.py (app API on 9612)"
echo "[brave/start] websockify (UI + VNC WebSocket on 9611)"
echo "[brave/start] ----"
echo "[brave/start] start.log ends here because bash is about to exec into"
echo "[brave/start] websockify, which is the foreground process from now on."
echo "[brave/start] For ongoing output switch the Source dropdown to one of:"
echo "[brave/start] websockify — HTTP + WebSocket access log"
echo "[brave/start] brave — Chromium stdout/stderr"
echo "[brave/start] control — sidecar API access log"
echo "[brave/start] Or open the Brave tab above to use the browser."
echo "[brave/start] ========================================"
# websockify is the foreground process. When it dies (or is killed by stop.sh),
# start.sh exits and the parent bash session terminates — which is the natural
# signal that the app is down.
exec websockify --web=/opt/brave-ui 0.0.0.0:9611 localhost:5901 \
> /root/.vnc/websockify.log 2>&1