Closes the gap behind the vpn-recreate bug: when the shared network is
recreated with a different /24, every app's stored static IP is left
outside it and adoptDockerSubnet only realigns CFG, not the apps.
- networkScanConflicts (network_conflicts.sh): read-only scan diffing each
active network_resources IP against docker's real subnet (via ipInSubnet).
Per-service routing-aware — skips gateway-routed services whose ipv4 is
commented out in the deployed compose, so gluetun apps don't false-positive.
Distinguishes 'daemon down' (benign) from 'network missing' (real).
- webuiSystemNetworkCheck (webui_system_network.sh): self-throttled generator
that writes frontend/data/system/network_status.json (modelled on
verify_status.json). Wired into webuiSystemUpdate AND run unconditionally
every ~60s from the task-processor poll (regen webui is mtime-gated and
would never fire on drift, which touches no source file).
- networkHealConflicts (network_heal.sh) + 'libreportal system network
check|heal [app]': the heal adopts docker's subnet in-process, then re-IPs
stranded apps with reset_network=ip (ports preserved), gluetun first.
Mutating path runs only through the task system (dual-mode, like update
apply); read-only check runs inline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
maybeRegenPoll truncates $REGEN_POLL_STAMP (.regen_poll_at) to throttle the
self-heal 'regen webui' poll, but the stamp lives in the docker-install-owned
TASK_DIR — the manager-run processor can't write there, so the truncate
EACCES'd every poll (swallowed by || true). The stamp never updated, so the
throttle read last=0 forever and 'regen webui' ran on every idle tick (and
spammed the journal ~16x/min).
Fix: pre-create the stamp world-writable in setupTaskDir, exactly like the
lock file and FIFO already are (runFileOp install -m 666). Truncate then
lands, the mtime advances, and the poll throttles to REGEN_POLL_INTERVAL.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>
The task processor is a systemd-service daemon, not a cron job — move it out
of the misleadingly-named scripts/crontab/task/ to scripts/task/.
To stop the systemd unit from baking the processor's in-tree path (the footprint
coupling that forces a reinstall on every reorg), the unit now ExecStarts the
stable wrapper: /usr/local/bin/libreportal __task-processor. start.sh intercepts
that early (after paths.sh, before the heavy load), exports install_scripts_dir,
and exec's the processor with start_script. Future moves/renames need only the
one hand-off updated + a regen — no footprint bump.
- git mv scripts/crontab/task -> scripts/task (filenames kept; cron-watchdog grep
+ function names unchanged)
- libreportal-svc: ExecStart -> stable wrapper launcher
- start.sh: __task-processor internal launcher (export install_scripts_dir; exec)
- crontab_task_processor.sh: fix self-location ../.. -> .. for the new 1-level
depth (latent bug the move would otherwise have introduced)
- regen files_*/function_manifest; add task_scripts to the app/cli aggregates
- footprint_version 3 -> 4 (root-owned svc unit changed -> needs a root reinstall)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: librelad <librelad@digitalangels.vip>