From cd004fbdde6340a0337dd5b1650af4dcf6fcfe03 Mon Sep 17 00:00:00 2001 From: Mathieu Moran Date: Mon, 10 Aug 2026 17:22:02 -0400 Subject: [PATCH] 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 <223556219+Copilot@users.noreply.github.com> --- PLAN.md | 14 +++++++++++--- modules/app_device_sync.py | 28 ++++++++++++++++++++-------- server/README.md | 16 ++++++++++++++++ server/docker-compose.yml | 1 + 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/PLAN.md b/PLAN.md index a364090..de3f170 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1526,6 +1526,10 @@ phase roadmap. - Server endpoints accessible via `/api/device-config` - Pi thread starts on boot (check logs for connectivity attempts) - Sync disabled if `YARIS_SERVER_URL` or `YARIS_DEVICE_KEY` not set +- **2026-08-10 access verification**: SSH access confirmed to Pi at `yaris@192.168.50.213` + (new WiFi card/subnet) and to unraid via `ssh unraid` (`root@192.168.10.10`). + 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) - 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@`. Confirm current IP before connecting (varies by 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 `origin/shameless-aislop`, the repo's current default branch (repo is public). - **unraid server SSH**: `ssh root@192.168.10.10` (alias `unraid`). Real git checkout lives at `/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`. - 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@` (alias `yarisobd`) -> `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 diff --git a/modules/app_device_sync.py b/modules/app_device_sync.py index 203fc44..9de27e1 100644 --- a/modules/app_device_sync.py +++ b/modules/app_device_sync.py @@ -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. """ +import os +import subprocess import threading import time -import os + import requests -from . import app_sql + +from . import app_network, app_sql _SYNC_THREAD = None @@ -16,6 +19,20 @@ _SYNC_STOP = False _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(): """Start background device config sync thread.""" global _SYNC_THREAD, _SYNC_STOP @@ -49,12 +66,7 @@ def _sync_loop(): while not _SYNC_STOP: try: - # Check if internet is available (simple connectivity test) - try: - requests.head("http://8.8.8.8", timeout=2) - is_connected = True - except (requests.RequestException, Exception): - is_connected = False + is_connected = _has_internet() if is_connected: # Fetch device config from server diff --git a/server/README.md b/server/README.md index 7c72d58..6d4b58e 100644 --- a/server/README.md +++ b/server/README.md @@ -66,6 +66,22 @@ so a permissive origin can't be used to steal a logged-in session. 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 Run this once per device (e.g. once for the Pi) after the stack is up: diff --git a/server/docker-compose.yml b/server/docker-compose.yml index 9be0dc7..d4b6e57 100644 --- a/server/docker-compose.yml +++ b/server/docker-compose.yml @@ -11,6 +11,7 @@ services: - ${DATA_DIR:-./data}/postgres:/var/lib/postgresql/data - ./sql/init.sql:/docker-entrypoint-initdb.d/init.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: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-yarisobd}"] interval: 10s