Files
Varaverk/Plugin/unraid/Tools/README-Tools.md
T
Gmer4Lfe 1ed6b92118 Document the Unraid platform layer
The folder that translates the OS into Varaverk's vocabulary had no docs of its own, so the
adapter contract and the three-layer web UI were only discoverable by reading the code.
2026-08-01 23:20:52 -04:00

6.1 KiB

━━━━━ PLUGIN / UNRAID / TOOLS ━━━━━

Platform-specific tooling for the WebGUI and the Unraid installation itself. Two of these keep the UI fast, two are operator tools for specific recovery and migration situations.

They live here rather than in the top-level Tools/ because each one manipulates something Unraid-specific — share .cfg files, the plugin's own PHP payload builders, or the installation's storage location.

File Type Runs
api_cache_writer.sh + .php UI cache Every minute via cron
remote_arr_cache_writer.sh UI cache Every 2 hours via cron
recreate_shares.sh Recovery Manual — after a rebuild or fresh install
storage_migrate.sh Migration Manual — switching storage mode

━━━ THE CACHE WRITERS — WHY PAGES LOAD INSTANTLY ━━━

The monitor and arrs pages present a lot of state: per-core CPU, memory, network, GPUs, containers, VMs, transcodes, arr library counts. Building that live on every page view means dozens of API calls and docker inspect runs per refresh, from a WebGUI that is already the first thing to slow down under load.

Instead, both are written to /tmp/vv_cache (tmpfs — RAM-speed reads, cleared on reboot) and the pages serve from there.

api_cache_writer.sh — local payloads, every minute

A deliberate one-line shim: php api_cache_writer.php. All logic is in the PHP because the payload builders (vv_monitor_*, vv_arrs_*) are the same functions the live API endpoints call. A bash reimplementation would be a second version of the same payload, free to drift.

Nothing here is allowed to break the UI:

  • A failed run simply leaves the cache unrefreshed — pages fall back to live calls. Slower, still correct.
  • A missing or unparseable cache is treated as absent, never as empty data.
  • ?live=1 bypasses the cache entirely.
  • Runs unprivileged with no lock — a torn cache file is replaced within 60 seconds, and every reader already has the live fallback.

🌐 remote_arr_cache_writer.sh — partner payloads, every 2 hours

SSHes to each partner and calls vv_arrs_local_node() on their PHP stack, caching the result locally as arrs_remote_<hostid>.json.

The partner builds its own payload rather than this host querying the partner's arr APIs directly. That matters: the partner already has working local URLs and API keys for its own arrs, so no cross-host credentials and no path mapping are involved. This host never holds keys for a remote's arrs.

A partner whose Tailscale IP will not resolve is skipped, not fatal — the arrs page shows what it has and falls back for the rest.


━━━ THE OPERATOR TOOLS ━━━

🗂️ recreate_shares.sh — after a rebuild

Recreates share directories on the correct disks by reading /boot/config/shares/*.cfg and honouring each share's shareInclude disk list.

The .cfg files are Unraid's own record of what a share is and which disks it spans — they are the source of truth, not a list Varaverk maintains. Typically needed on a host after a full disk replacement or fresh install, where the config survived but the folders did not.

Create only, never delete. A directory that already exists is left alone. This runs at a moment when the operator's picture of what should exist may be out of date, and removing anything on that basis is how a recovery step becomes a data-loss step.

Refuses to run without /mnt/user mounted. Creating share directories against an unmounted array writes them into the underlying root filesystem, where they then shadow the real shares once the array does mount.

📦 storage_migrate.sh — moving the whole installation

Relocates Varaverk between the two storage modes:

Mode SCRIPTS_DIR Trade-off
Internal /boot/config/plugins/varaverk Direct git pull/push. Available before the array mounts.
Flash /mnt/user/appdata/Varaverk Preserves USB flash lifetime. Array must be started for Varaverk to function at all.

This is the most destructive script in the folder — rsync --delete, cp -a, rm -rf — and it rewrites the pointers everything else derives from:

  varaverk.cfg   SCRIPTS_DIR                    ← the authoritative path
  master.conf    TARGET_DIR
  host*.conf     HOST*_STORAGE_MODE_INTERNAL
  varaverk.cron  regenerated so job paths follow the new SCRIPTS_DIR

STATE_DIR, DATA_DIR, PERSISTENT_CONF_CACHE and every orchestrator job path are built from SCRIPTS_DIR. Changing storage mode moves all of them at once, which is why the cron is regenerated rather than edited.

In flash mode, git_pull_execute.sh syncs Plugin/ back to /boot/ after each pull, so the WebGUI keeps serving current PHP even though the scripts live in appdata.


━━━ SAFEGUARDS ━━━

The cache writers are deliberately unprivileged and lockless. Their output is regenerable within a minute and every consumer has a live fallback. There is no privileged operation to gate and no state worth locking. This is documented in their headers so it is not "corrected" later.

The operator tools are the opposite. Both enforce root, take a lock, and support --dry-run. storage_migrate.sh additionally exits cleanly if already in the requested mode, and removes the old location only once the new one is confirmed in place.

recreate_shares.sh will not act on an unmounted array — see above; this is the guard that prevents shadow directories.


━━━ RELATIONSHIP TO THE WEB UI ━━━

  pages/monitor.php ─┐
                     ├─► include/monitor.php  (vv_monitor_*)
  api/monitor.php ───┘            ▲
                                  │
  Tools/api_cache_writer.php ─────┘   same builders → cache can't disagree with live
        │
        └─► /tmp/vv_cache/monitor.json ──► served by api/monitor.php unless ?live=1

Adding a metric means adding it in include/ once. The page, the live endpoint, and the cache all pick it up together.