lm-sensors prints high= and crit= on the same line as the reading, so scraping
the line for its largest number reported a flat 100C on Intel while the shell's
last-field parse got a bare ")" and never fired at all. One parse in the
adapter now, preferring Tdie over Tctl since Tctl carries a +27C offset.
All 16 include/ files now carry PURPOSE / DESIGN PRINCIPLES / OPERATIONAL
SAFEGUARDS / EXPORTS / CONFIGURATION, keeping the first three section names
identical to the bash headers so retrieval can route across both languages.
monitor.php read six watchdog state files from /tmp while the watchdogs write
to STATE_DIR, so every strike set came back empty and the summary reported
healthy unconditionally. docs.php gained path containment before it is wired
to a page.
Unraid truncates the Server Name to 15 chars (NetBIOS limit). HOST2's
real hostname is "unRAID-Jayred36" but master.conf's HOST2 (matching
what Tailscale shows for this peer, since resolve_tailscale_ip() keys
off the same value) is the untruncated "unRAID-Jayred365" — confirmed
live, Tailscale's own Self.HostName on that machine is truncated too.
vv_detect_host() did a strict case-insensitive match against the bare
`hostname -s` output with no tolerance for this, so it always returned
'unknown' on HOST2. That silently broke the first-run wizard (Varaverk.page
explicitly excludes 'unknown' from the "needs setup" check) even though
host2.conf never existed, plus vv_partner_state() and vv_fallback_active()
in monitor.php which independently reimplemented the same hostname
comparison instead of calling vv_detect_host().
Fix: vv_detect_host() falls back to a prefix match when the local hostname
is exactly 15 chars; vv_partner_state()/vv_fallback_active() now call
vv_detect_host() instead of duplicating the comparison. Verified live on
HOST2 — vv_detect_host() now returns 'host2', partner state correctly
flags HOST2 as is_me, and the wizard-trigger condition now evaluates true.
All state/data file paths in scripts and PHP now resolve via STATE_DIR / DATA_DIR /
PERSISTENT_CONF_CACHE instead of hardcoded /boot/config/ or /tmp/ paths, so the
ecosystem works in both internal and appdata storage modes.
PHP layer (watchdog.php, partnership.php, fallback.php, monitor.php, snapshot.php,
config.php): all state reads switched to STATE_DIR constant; remote state reads use
the new vv_remote_state_cmd() helper which resolves the remote's SCRIPTS_DIR via
their varaverk.cfg before building the path.
conf_sync.sh: fixed SCRIPTS_ROOT → SCRIPTS_DIR bug on MY_CONF path; added
_remote_scripts_dir() to resolve partner's SCRIPTS_DIR before SCP pull.
fallback.php page: added controls card (PARTNERSHIP_ENABLED, FALLBACK_ENABLED,
FALLBACK_RSYNC_ENABLED toggles), status grid, and settings card.
README and Manual updated for System_Essentials, Watchdogs, Fallback, Rsync,
Media, Monitors, Orchestrators, Partnership: added new scripts (conf_sync,
conf_cache_save/restore, conf_cache_watchdog, play_state_sync, start_webhook_listener,
upgrade_webhook_handler), corrected all stale /boot/config/ state file paths to
$STATE_DIR/$DATA_DIR, noted webgui/php_fpm/mover/user_scripts scripts moved to
Plugin/unraid/System_Essentials, fixed start_webhook_listener.sh header (Node.js,
not PHP -S).
Adds require_partnership() to common.sh — exits cleanly when PARTNERSHIP_ENABLED=false.
Removes FALLBACK_PARTNERSHIP_REQUIRED toggle — partnership is now always required,
not optional. Cross-server scripts (rsync, conf sync, fallback, arr sync, play state,
backup verify) all call require_partnership after detect_hosts.
All FALLBACK_${MY_ID}_COVERS_${REMOTE_ID}_TIER* references updated to
FALLBACK_${REMOTE_ID}_TIER* across fallback_test.sh, partnership_manager.sh,
docker_update.sh, mesh_monitor.sh, and monitor.php. mesh_monitor.sh drops
the inner covering-host loop — tier data now lives in the covered host's own
conf so no cross-host scan is needed. monitor.php reads from the covered
host's conf file rather than the local host's.
Web files now served via symlink to the git repo so git pull changes survive
reboots without rebuilding the txz. Also includes: docker pull/rebuild/restart
with live log streaming, arr_profile_enforcer for Sonarr/Radarr quality
profiles, monitor page cache fix (background writer now in cron), and
ARR_KIDS/SONARR/RADARR profile name vars in master.conf.
New span-1 card shows global RSYNC_ENABLED gate, per-window badges (C/D/I/W),
active profile names + elapsed time from lock files, and last-sync timestamp
per orchestrator window from script log files.
GPU shrunk from span 2 to span 1 to make room. Row 3 is now:
Rsync(1) | GPU(1) | Transcode(2) | Streams(4)
- Move SCRIPTS_DIR/DATA_DIR/STATE_DIR from appdata to /boot/config/plugins/varaverk
- All state files now in STATE_DIR (no more /tmp or /boot/config root writes)
- Bootstrap: Gitea-first clone with GitHub fallback, no array dependency
- varaverk.cfg seeded with Gitea connection settings
- .gitignore: add State_Files/, varaverk.cfg, varaverk-*.txz
- Partnership/transcode/fallback scripts use STATE_DIR variables
- PHP config.php: DATA_DIR/STATE_DIR constants, VV_SETUP_STATE_FILE dynamic
- deploy.sh PROD_ROOT updated to plugin flash dir
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
vv_partner_state() now reads setup.db and adds onboard_phase (0/1/2/null)
to each host entry.
Partner card JS renders a badge under the hostname for remote hosts that
haven't completed Phase 2: amber "Awaiting onboard" (phase 1) or grey
"Not provisioned" (phase 0). Phase 2 complete shows nothing extra.
include/monitor.php: vv_fallback_state() now returns:
enabled, check_interval, handback_strikes, handback_strikes_required,
partnership_suspended, partner_lost_at, partnership_required,
partnership_suspend_after — all read from state file + conf vars.
pages/monitor.php: fallback card render rebuilt:
Disabled: clear message with how to enable
Suspended: partnership inactive with elapsed time
FAILOVER: outage duration + T1/T2/T3/T4 tier badges (active=green,
pending=dark) + handback strike progress dots (●●○) when remote
comes back and strikes are counting
NO_INTERNET/DARK: short contextual line
NORMAL: quiet "monitoring · 30s · partnership gated" meta line
Accent border: disabled/suspended → warn, NORMAL → ok, FAILOVER → err
PHP architecture:
- Extract common.php from monitor.php — shared system functions (vv_system_info,
vv_memory_breakdown, vv_remote_hosts_stats, disk/GPU/UPS/network/docker/parity, etc.)
now live in one place; monitor.php and watchdog.php both require common.php
- Add unraid_api.php as explicit include (was implicit via config.php chain)
- confform.php: add missing require_once config.php (implicit dep made explicit)
- Delete orphaned pages/docs.php and pages/config.php (absorbed into scheduler)
Watchdog page:
- Add Storage watchdog card (growth + log strikes, baseline age, suppress ceilings)
- Add Network watchdog card (NPM strikes, DDNS domain/container, NPM URL)
- One host per row layout — all 5 watchdog cards equally spaced via inner grid
- Watchdog now uses Unraid API for local system stats; remote nodes with API key
but no SSH get system info from vv_remote_hosts_stats() with api_only flag
- SSH bundle: /proc/meminfo passed as raw section instead of awk-parsed header
fields — fixes RAM showing 0 on remote hosts where awk quoting was unreliable
- vv_wd_local_system() rewritten as thin wrapper over vv_system_info() + vv_memory_breakdown()
Monitor page:
- Watchdog card: add stability strikes, storage watchdog strikes, network NPM status,
live system stats (rootfs/log/tmp %, RAM free, load, CPU temp, zombies, NIC, sshd)
- Row height: switch from max-height on cards to minmax(0, calc(...)) on grid track —
all cards in a row now fill to the tallest card's height correctly (fixes Pools card
being shorter than neighbours)
Scheduler page:
- Add Tools section above Custom Scripts — lists Tools/*.sh with run/dry-run/cron/log
- vv_tools_scripts() function in scheduler.php include
Tools:
- Add docker_prune_images.sh — removes dangling Docker images; --dry-run and --status modes