fix: wire Phase 25.5a deploy docs and sync connectivity

- use app_network status for device sync connectivity checks
- mount migrate_phase25_5a.sql in server docker compose
- document manual server upgrade migration steps
- record verified Pi and unraid SSH access details in PLAN

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-10 17:22:02 -04:00
co-authored by Copilot
parent 0bda44a7bc
commit cd004fbdde
4 changed files with 48 additions and 11 deletions
+11 -3
View File
@@ -1526,6 +1526,10 @@ phase roadmap.
- Server endpoints accessible via `/api/device-config` - Server endpoints accessible via `/api/device-config`
- Pi thread starts on boot (check logs for connectivity attempts) - Pi thread starts on boot (check logs for connectivity attempts)
- Sync disabled if `YARIS_SERVER_URL` or `YARIS_DEVICE_KEY` not set - Sync disabled if `YARIS_SERVER_URL` or `YARIS_DEVICE_KEY` not set
- **2026-08-10 access verification**: SSH access confirmed to Pi at `[email protected]`
(new WiFi card/subnet) and to unraid via `ssh unraid` (`[email protected]`).
At verification time, Pi checkout was still on `d7b9bb6` and unraid server checkout on
`24a2323`, so both still need a deploy/pull to pick up the latest Phase 25.5a code.
#### Next phase (Phase 25.5b) #### Next phase (Phase 25.5b)
- Hot-reload handler to apply config changes without restart - Hot-reload handler to apply config changes without restart
@@ -1561,14 +1565,18 @@ phase. Scope, at a high level (not yet designed in detail):
- **Pi credentials/SSH**: `ssh yaris@<pi-ip>`. Confirm current IP before connecting (varies by - **Pi credentials/SSH**: `ssh yaris@<pi-ip>`. Confirm current IP before connecting (varies by
network — check locally, not recorded here) — usually reachable via `yaris.local` too (mDNS, network — check locally, not recorded here) — usually reachable via `yaris.local` too (mDNS,
see Phase 6). see Phase 6). **Current verified LAN IP (2026-08-10): `192.168.50.213`** after the TP-Link
Archer T3U WiFi change.
- **Local dev repo**: work happens on a separate dev machine, not on the Pi. Push to - **Local dev repo**: work happens on a separate dev machine, not on the Pi. Push to
`origin/shameless-aislop`, the repo's current default branch (repo is public). `origin/shameless-aislop`, the repo's current default branch (repo is public).
- **unraid server SSH**: `ssh [email protected]` (alias `unraid`). Real git checkout lives at - **unraid server SSH**: `ssh [email protected]` (alias `unraid`). Real git checkout lives at
`/mnt/user/app/git/yaris-obd` (not `/mnt/user/appdata/...`, which is only the docker-managed data `/mnt/user/app/git/yaris-obd` (not `/mnt/user/appdata/...`, which is only the docker-managed data
volume for the `db`/`dashcam` containers). Deploy with volume for the `db`/`dashcam` containers). **Re-verified 2026-08-10**: alias works and lands in
`/root`. Deploy with
`cd /mnt/user/app/git/yaris-obd && git pull --ff-only && cd server && docker compose up -d --build`. `cd /mnt/user/app/git/yaris-obd && git pull --ff-only && cd server && docker compose up -d --build`.
Container names: `yaris-obd-db` (Postgres 17), `yaris-obd-api`. Container names: `yaris-obd-db` (Postgres 17), `yaris-obd-api`. For existing databases, also run
the mounted migration scripts manually, e.g.
`docker compose exec db psql -U yarisobd -d yarisobd -f /docker-entrypoint-initdb.d/migrate_phase25_5a.sql`.
- **Pi deploy loop**: `ssh yaris@<pi-ip>` (alias `yarisobd`) -> - **Pi deploy loop**: `ssh yaris@<pi-ip>` (alias `yarisobd`) ->
`cd ~/app/yaris-obd && git pull --ff-only` -> `sudo systemctl restart yaris-obd.service` `cd ~/app/yaris-obd && git pull --ff-only` -> `sudo systemctl restart yaris-obd.service`
(passwordless sudo confirmed via `yaris ALL=(ALL) NOPASSWD: ALL`). App stdout/stderr goes to (passwordless sudo confirmed via `yaris ALL=(ALL) NOPASSWD: ALL`). App stdout/stderr goes to
+20 -8
View File
@@ -4,11 +4,14 @@ Pi fetches device config from server when internet is available (connection-driv
Stores in SQLite and hot-reloads app globals if config changes. Stores in SQLite and hot-reloads app globals if config changes.
""" """
import os
import subprocess
import threading import threading
import time import time
import os
import requests import requests
from . import app_sql
from . import app_network, app_sql
_SYNC_THREAD = None _SYNC_THREAD = None
@@ -16,6 +19,20 @@ _SYNC_STOP = False
_SYNC_CONFIG_VERSION = 0 # Track last-synced version to detect changes _SYNC_CONFIG_VERSION = 0 # Track last-synced version to detect changes
def _has_internet():
"""Use the existing NetworkManager-derived status instead of probing 8.8.8.8 over HTTP."""
try:
return app_network.get_status().get("internet_reachable", False)
except (
OSError,
subprocess.SubprocessError,
ValueError,
KeyError,
app_network.NetworkConfigurationError,
):
return False
def start_sync(): def start_sync():
"""Start background device config sync thread.""" """Start background device config sync thread."""
global _SYNC_THREAD, _SYNC_STOP global _SYNC_THREAD, _SYNC_STOP
@@ -49,12 +66,7 @@ def _sync_loop():
while not _SYNC_STOP: while not _SYNC_STOP:
try: try:
# Check if internet is available (simple connectivity test) is_connected = _has_internet()
try:
requests.head("http://8.8.8.8", timeout=2)
is_connected = True
except (requests.RequestException, Exception):
is_connected = False
if is_connected: if is_connected:
# Fetch device config from server # Fetch device config from server
+16
View File
@@ -66,6 +66,22 @@ so a permissive origin can't be used to steal a logged-in session.
curl http://localhost:8098/health curl http://localhost:8098/health
``` ```
### Upgrading an existing unraid deployment
If the Postgres volume already exists, mounted migration files do **not** run
again automatically. After pulling new code, apply the new migrations manually:
```bash
cd /mnt/user/app/git/yaris-obd/server
docker compose exec db psql -U yarisobd -d yarisobd -f /docker-entrypoint-initdb.d/migrate_phase24.sql
docker compose exec db psql -U yarisobd -d yarisobd -f /docker-entrypoint-initdb.d/migrate_phase25_5a.sql
docker compose up -d --build
```
Phase 25.5a adds the device identity sync columns (`owner_name`, `car_model`,
`device_name`, `avatar_path`, `config_version`, `config_updated_at`) used by the
Pi/server config sync flow.
## Registering a device and getting an API key ## Registering a device and getting an API key
Run this once per device (e.g. once for the Pi) after the stack is up: Run this once per device (e.g. once for the Pi) after the stack is up:
+1
View File
@@ -11,6 +11,7 @@ services:
- ${DATA_DIR:-./data}/postgres:/var/lib/postgresql/data - ${DATA_DIR:-./data}/postgres:/var/lib/postgresql/data
- ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
- ./sql/migrate_phase24.sql:/docker-entrypoint-initdb.d/migrate_phase24.sql:ro - ./sql/migrate_phase24.sql:/docker-entrypoint-initdb.d/migrate_phase24.sql:ro
- ./sql/migrate_phase25_5a.sql:/docker-entrypoint-initdb.d/migrate_phase25_5a.sql:ro
healthcheck: healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-yarisobd}"] test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-yarisobd}"]
interval: 10s interval: 10s