UI overhaul, VPN management, controlsd fix, screen recorder removal
- Fix controlsd crash: self.state.name AttributeError when state is int - Move telemetry tlog import to module level in carstate.py (was per-frame) - Remove FrogPilot screen recorder from UI (was crashing OMX on init) - Ready screen: boot logo background, 8-bit READY! sprite, error states (panda not connected, car not recognized) with 10s startup grace period - ClearPilot menu: always opens to General, QButtonGroup for sidebar, System Status uses ButtonControl, VPN toggle with process control - Sidebar hidden on construction (no flash before splash) - Status window: threaded data collection (QtConcurrent), panda detection via scene.pandaType (SPI, not USB), only refreshes when visible - VPN: moved to system/clearpilot/, SIGTERM graceful shutdown, keepalive ping through tunnel, killall openvpn on disable, launched from launch_openpilot.sh instead of continue.sh - Disable gpsd and dashcamd temporarily for perf testing Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
153
system/clearpilot/vpn-monitor.sh
Executable file
153
system/clearpilot/vpn-monitor.sh
Executable file
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# VPN monitor — connects OpenVPN when internet is up, disconnects when down.
|
||||
# Drops and reconnects when WiFi SSID changes (stale tunnel prevention).
|
||||
# On non-home networks, resolves VPN hostname via 8.8.8.8 and passes IP directly.
|
||||
# Keepalive: pings gateway through tunnel, two failures 10s apart = reconnect.
|
||||
# SIGTERM: gracefully stops tunnel and exits.
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CONF="$SCRIPT_DIR/vpn.ovpn"
|
||||
VPN_HOST="vpn.hanson.xyz"
|
||||
VPN_PORT="1194"
|
||||
HOME_SSID="risa"
|
||||
VPN_GW="192.168.69.1"
|
||||
CHECK_HOST="1.1.1.1"
|
||||
INTERVAL=30
|
||||
CONNECT_TIMEOUT=30
|
||||
MAX_FAILURES=3
|
||||
PREV_SSID=""
|
||||
FAIL_COUNT=0
|
||||
ACTIVE_VPN_IP=""
|
||||
|
||||
kill_vpn() {
|
||||
killall openvpn 2>/dev/null
|
||||
# Clean up host route to VPN server
|
||||
if [ -n "$ACTIVE_VPN_IP" ]; then
|
||||
ip route del "$ACTIVE_VPN_IP/32" 2>/dev/null
|
||||
ACTIVE_VPN_IP=""
|
||||
fi
|
||||
}
|
||||
|
||||
get_default_gw() {
|
||||
ip route show default | awk '/via/ {print $3; exit}'
|
||||
}
|
||||
|
||||
resolve_vpn() {
|
||||
if [ "$CURR_SSID" != "$HOME_SSID" ]; then
|
||||
dig +short @8.8.8.8 "$VPN_HOST" 2>/dev/null | tail -1
|
||||
else
|
||||
dig +short "$VPN_HOST" 2>/dev/null | tail -1
|
||||
fi
|
||||
}
|
||||
|
||||
# Graceful shutdown on SIGTERM
|
||||
shutdown() {
|
||||
echo "$(date): SIGTERM received, stopping vpn and exiting"
|
||||
kill_vpn
|
||||
exit 0
|
||||
}
|
||||
trap shutdown SIGTERM SIGINT
|
||||
|
||||
# Kill other instances of this script and wait for graceful shutdown
|
||||
for pid in $(pgrep -f 'vpn-monitor.sh' | grep -v $$); do
|
||||
kill "$pid" 2>/dev/null
|
||||
done
|
||||
sleep 5
|
||||
# Force kill any that didn't exit
|
||||
for pid in $(pgrep -f 'vpn-monitor.sh' | grep -v $$); do
|
||||
kill -9 "$pid" 2>/dev/null
|
||||
done
|
||||
|
||||
# Kill any existing VPN and clean up
|
||||
kill_vpn
|
||||
sleep 1
|
||||
|
||||
while true; do
|
||||
CURR_SSID="$(iwgetid -r 2>/dev/null)"
|
||||
|
||||
# Detect SSID change (only when switching between two known networks)
|
||||
if [ -n "$PREV_SSID" ] && [ -n "$CURR_SSID" ] && [ "$PREV_SSID" != "$CURR_SSID" ]; then
|
||||
echo "$(date): wifi changed from '$PREV_SSID' to '$CURR_SSID', dropping vpn"
|
||||
kill_vpn
|
||||
FAIL_COUNT=0
|
||||
sleep 5
|
||||
fi
|
||||
PREV_SSID="$CURR_SSID"
|
||||
|
||||
if ping -c 1 -W 3 "$CHECK_HOST" > /dev/null 2>&1; then
|
||||
# Internet is up — check tunnel health if connected
|
||||
if ip link show tun0 > /dev/null 2>&1; then
|
||||
# Keepalive: ping gateway through tunnel, two failures 10s apart = dead
|
||||
if ! ping -c 1 -W 3 -I tun0 "$VPN_GW" > /dev/null 2>&1; then
|
||||
sleep 10
|
||||
if ! ping -c 1 -W 3 -I tun0 "$VPN_GW" > /dev/null 2>&1; then
|
||||
echo "$(date): keepalive failed twice, dropping vpn"
|
||||
kill_vpn
|
||||
sleep 5
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Start VPN if not running
|
||||
if ! ip link show tun0 > /dev/null 2>&1; then
|
||||
if [ "$FAIL_COUNT" -ge "$MAX_FAILURES" ]; then
|
||||
# Back off after repeated failures — just wait for next interval
|
||||
sleep "$INTERVAL"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Resolve VPN server IP (via 8.8.8.8 on non-home networks)
|
||||
RESOLVED_IP="$(resolve_vpn)"
|
||||
if [ -z "$RESOLVED_IP" ]; then
|
||||
echo "$(date): failed to resolve $VPN_HOST (ssid=$CURR_SSID)"
|
||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||
sleep "$INTERVAL"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Add host route to VPN server via current default gateway
|
||||
# so VPN traffic survives tun0 coming up
|
||||
GW="$(get_default_gw)"
|
||||
if [ -n "$GW" ]; then
|
||||
ip route replace "$RESOLVED_IP/32" via "$GW"
|
||||
echo "$(date): host route $RESOLVED_IP via $GW"
|
||||
fi
|
||||
ACTIVE_VPN_IP="$RESOLVED_IP"
|
||||
|
||||
echo "$(date): starting openvpn -> $RESOLVED_IP (attempt $((FAIL_COUNT + 1))/$MAX_FAILURES, ssid=$CURR_SSID)"
|
||||
nice -n 19 openvpn --config "$CONF" --remote "$RESOLVED_IP" "$VPN_PORT" --daemon --log-append /tmp/openvpn.log
|
||||
|
||||
# Wait for tunnel to come up
|
||||
CONNECTED=0
|
||||
for i in $(seq 1 "$CONNECT_TIMEOUT"); do
|
||||
if ip link show tun0 > /dev/null 2>&1; then
|
||||
CONNECTED=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
if [ "$CONNECTED" -eq 1 ]; then
|
||||
echo "$(date): vpn connected (took ${i}s)"
|
||||
FAIL_COUNT=0
|
||||
else
|
||||
echo "$(date): vpn failed to connect within ${CONNECT_TIMEOUT}s, killing"
|
||||
kill_vpn
|
||||
FAIL_COUNT=$((FAIL_COUNT + 1))
|
||||
if [ "$FAIL_COUNT" -ge "$MAX_FAILURES" ]; then
|
||||
echo "$(date): $MAX_FAILURES consecutive failures, backing off"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
# Internet is down — kill VPN if running
|
||||
if ip link show tun0 > /dev/null 2>&1; then
|
||||
echo "$(date): internet down, stopping openvpn"
|
||||
kill_vpn
|
||||
fi
|
||||
FAIL_COUNT=0
|
||||
fi
|
||||
sleep "$INTERVAL"
|
||||
done
|
||||
76
system/clearpilot/vpn.ovpn
Normal file
76
system/clearpilot/vpn.ovpn
Normal file
@@ -0,0 +1,76 @@
|
||||
client
|
||||
dev tun
|
||||
proto udp
|
||||
remote vpn.hanson.xyz 1194
|
||||
resolv-retry infinite
|
||||
nobind
|
||||
persist-key
|
||||
persist-tun
|
||||
remote-cert-tls server
|
||||
cipher AES-256-GCM
|
||||
auth SHA256
|
||||
verb 3
|
||||
pull-filter ignore "redirect-gateway"
|
||||
# pull-filter ignore "route "
|
||||
|
||||
<ca>
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB2jCCAX+gAwIBAgIUFVGjbK1Qb5d3RkkoNPMsXeI/xVAwCgYIKoZIzj0EAwIw
|
||||
HjEcMBoGA1UEAwwTT3BlblZQTi1JbnRlcm5hbC1DQTAgFw0yNjAyMDcwODQ3Mzda
|
||||
GA8yMTI2MDExNDA4NDczN1owHjEcMBoGA1UEAwwTT3BlblZQTi1JbnRlcm5hbC1D
|
||||
QTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABGb6RWOFnCJ9t7X5q6fqpv0y3Hg/
|
||||
dTU3ky+MAjfPRYfUWfiM7wVKubYOCc+pUHsJXWaghqu7nQoCeSzVDcPXlWGjgZgw
|
||||
gZUwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUNThAWabF1zsqNE19iCKuZMjHBIUw
|
||||
WQYDVR0jBFIwUIAUNThAWabF1zsqNE19iCKuZMjHBIWhIqQgMB4xHDAaBgNVBAMM
|
||||
E09wZW5WUE4tSW50ZXJuYWwtQ0GCFBVRo2ytUG+Xd0ZJKDTzLF3iP8VQMAsGA1Ud
|
||||
DwQEAwIBBjAKBggqhkjOPQQDAgNJADBGAiEA2mPwEK8G4HXlRu6WZVSRdqyCPYYd
|
||||
KffYalCXgw3pZ/sCIQC9qPNckHtubycu8kq4iM8Vl1vYMVEorn7DUFdXJCvtcg==
|
||||
-----END CERTIFICATE-----
|
||||
</ca>
|
||||
|
||||
<cert>
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB2TCCAYCgAwIBAgIRALuRBSB68/ccWM8SASfEIV0wCgYIKoZIzj0EAwIwHjEc
|
||||
MBoGA1UEAwwTT3BlblZQTi1JbnRlcm5hbC1DQTAgFw0yNjA0MTIwMDA1NDhaGA8y
|
||||
MTI2MDMxOTAwMDU0OFowEDEOMAwGA1UEAwwFY29tbWEwWTATBgcqhkjOPQIBBggq
|
||||
hkjOPQMBBwNCAAQ/jN83Z2Ikk+IWVPGxN0CNFCh74Yrb3W6VXAjGWa+ppVxSbdeq
|
||||
YVBWjJl6qSg6n2ZMDivQ5NcKgsxMcY9ly/LEo4GqMIGnMAkGA1UdEwQCMAAwHQYD
|
||||
VR0OBBYEFDIulLc8hAwTkGHq+z8K8eBBM0vVMFkGA1UdIwRSMFCAFDU4QFmmxdc7
|
||||
KjRNfYgirmTIxwSFoSKkIDAeMRwwGgYDVQQDDBNPcGVuVlBOLUludGVybmFsLUNB
|
||||
ghQVUaNsrVBvl3dGSSg08yxd4j/FUDATBgNVHSUEDDAKBggrBgEFBQcDAjALBgNV
|
||||
HQ8EBAMCB4AwCgYIKoZIzj0EAwIDRwAwRAIgR/ssLDNLmt1s0WXwGLszBUrlstUu
|
||||
9nhP2PcmdnsOit4CIECFbQ7RHEZLQJWsL2DvKowCCzDtA6ZGDILTVfHwNyDn
|
||||
-----END CERTIFICATE-----
|
||||
</cert>
|
||||
|
||||
<key>
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgYolghDmo5ISWxjQy
|
||||
sayXuFRSW5fkiIXJ1SGvSRLnmBmhRANCAAQ/jN83Z2Ikk+IWVPGxN0CNFCh74Yrb
|
||||
3W6VXAjGWa+ppVxSbdeqYVBWjJl6qSg6n2ZMDivQ5NcKgsxMcY9ly/LE
|
||||
-----END PRIVATE KEY-----
|
||||
</key>
|
||||
|
||||
<tls-crypt>
|
||||
#
|
||||
# 2048 bit OpenVPN static key
|
||||
#
|
||||
-----BEGIN OpenVPN Static key V1-----
|
||||
5d6fedacbb44013958eef494b179f21d
|
||||
51b158484c08cb125b8ddd2a919ed44f
|
||||
5cae951b1f85f483f0108b1000fac1e6
|
||||
334ab5b2f3c7352c3a53e814e2e4cdc7
|
||||
f401d5eb2e13449539313f18de53563d
|
||||
a72318979c31ef76caad86317064aede
|
||||
940ab3d799886b9667f4deabb8b159c2
|
||||
12bd7f27c91a7bfd3b9a315dbac3391d
|
||||
fb3c354b7955627937fd6163c1683705
|
||||
e46b252ee9c383507b5a4496462f3d67
|
||||
25dc48bbca8170574efa22b3c37c4bcc
|
||||
ad30e92d39aae5326c59a4484302d388
|
||||
7836837bd5098faeda430aa6db69d8df
|
||||
fe62aeed2bef6afb7c0c742fe8644040
|
||||
3c4e46deb3915467c351018592c58545
|
||||
5b5d7b8c204d37104f9848573d8eb73b
|
||||
-----END OpenVPN Static key V1-----
|
||||
</tls-crypt>
|
||||
Reference in New Issue
Block a user