feat(backend): runtime LAN-IP detection (netinfo helper) + manual override
The backend's bridge network can't see the host's NICs, so HOST_IP from install.sh went stale silently after a DHCP change. Now: - services/netinfo_helper.py runs as a new `netinfo` service (same backend image, network_mode: host): every 60s it picks the PHYSICAL LAN address (main-table default-route NIC if real hardware, else first real NIC with IPv4; never WireGuard/Tailscale/ZeroTier/bridges/veths, ignores 169.254) and writes it to the shared `netinfo` volume. Stdlib only. On Docker Desktop (linuxkit/WSL2 kernel) it reports "unsupported" instead of the VM's meaningless address. - services/lan_ip.py: one resolver used by /api/system/status (lan_ip + lan_ip_info), the pairing QR and the cloud heartbeat's local_ip: override (pos_settings network.lan_ip_override) → live detection (ignored when older than 5 min) → HOST_IP. Flags `mismatch` when a pinned address is no longer on any of the machine's NICs. - PUT /api/system/lan-ip-override (manager): set a private IPv4 or null to return to automatic; public/loopback/link-local/IPv6 rejected (422). - cloud_sync._get_local_ip uses the resolver (no more socket trick that returned the container IP). Tested: helper selection on a fake sysfs/route table (8 cases incl. VPN default routes) + real ioctl/route parsing on a Linux kernel; resolver priority/staleness/mismatch/validation (18 cases); isolated full stack: HOST_IP fallback on Docker Desktop, override save/validate/auth, simulated Linux detection incl. DHCP change and dead helper, heartbeat IP. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,19 @@ services:
|
||||
- ${DATA_PATH}:/app/data
|
||||
- ${LOGO_PATH}:/app/logo.png:ro
|
||||
- ${FISCAL_PATH}:/mnt/fiscal
|
||||
- netinfo:/netinfo:ro
|
||||
|
||||
# Finds the server's LAN IP on the PHYSICAL network (never a VPN) every minute
|
||||
# and shares it with the backend (pairing QR, manager, heartbeat). Needs the
|
||||
# host's network namespace because the backend's bridge network can't see
|
||||
# real NICs. Same image as the backend — see services/netinfo_helper.py.
|
||||
netinfo:
|
||||
image: ${REGISTRY}/pos-backend:${VERSION:-latest}
|
||||
restart: unless-stopped
|
||||
network_mode: host
|
||||
command: ["python", "-m", "services.netinfo_helper"]
|
||||
volumes:
|
||||
- netinfo:/netinfo
|
||||
|
||||
waiter_pwa:
|
||||
image: ${REGISTRY}/pos-waiter:${VERSION:-latest}
|
||||
@@ -44,3 +57,6 @@ services:
|
||||
- waiter_pwa
|
||||
- manager_dashboard
|
||||
restart: unless-stopped
|
||||
|
||||
volumes:
|
||||
netinfo:
|
||||
|
||||
Reference in New Issue
Block a user