Document the PHP api layer and fix what documenting it exposed
Writing down what each endpoint actually guarantees made the places it didn't obvious — shell arguments reaching a crontab or a bash -c unescaped, master.conf written without tmp+rename, and conf edits that could be saved without ever being parsed.
This commit is contained in:
@@ -1,4 +1,81 @@
|
||||
<?php
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
// PURPOSE
|
||||
// Full monitor payload. Every metric the monitor page renders — system, CPU, memory,
|
||||
// network, GPUs, disks and pools, array, parity, UPS, containers, VMs, transcodes, watchdog
|
||||
// and rsync summaries, and remote node roll-ups — in one document.
|
||||
//
|
||||
// OPERATIONAL MODEL
|
||||
// Deliberately one large response rather than many small ones. Most of these metrics share
|
||||
// an underlying source — the Unraid API, /proc, the same emhttp ini files — so collecting
|
||||
// them together means one pass over each source instead of one per endpoint. The page
|
||||
// renders from a single consistent snapshot; twenty parallel fetches would render from
|
||||
// twenty slightly different moments.
|
||||
//
|
||||
// Served from a 300s cache written by Tools/api_cache_writer.sh, which runs every minute.
|
||||
// The page therefore almost never pays for collection — the background writer does. ?live
|
||||
// forces a fresh build for the refresh button.
|
||||
//
|
||||
// DESIGN PRINCIPLES
|
||||
// The cache check happens before the heavy includes.
|
||||
// Only include/config.php is loaded to reach vv_cache_read(). monitor.php, vms.php and
|
||||
// docker_folders.php are required only after a miss, so a cache hit costs one file read
|
||||
// rather than parsing three libraries.
|
||||
//
|
||||
// The API cache is pre-warmed once, on purpose.
|
||||
// vv_api_data() is called before the payload is assembled so the API-first functions
|
||||
// below it share a single GraphQL round trip instead of each making their own.
|
||||
//
|
||||
// Every field is a named function call, in render order.
|
||||
// The payload is a flat map of key to collector. Adding a metric is adding a line, and
|
||||
// nothing in the assembly depends on anything else in it — so one expensive or broken
|
||||
// collector can be moved or removed without touching the others.
|
||||
//
|
||||
// Reports the API's own health alongside the data.
|
||||
// _api_status travels with the payload, so the page can show that a section degraded to
|
||||
// its local fallback rather than silently presenting less detail.
|
||||
//
|
||||
// OPERATIONAL SAFEGUARDS
|
||||
// Read-only. Every function here observes; none of them start, stop, or change anything.
|
||||
//
|
||||
// Cache miss is distinguished from empty payload.
|
||||
// vv_cache_read() returns null on a miss, expiry, or unparseable file, and the check is
|
||||
// an explicit !== null — so a legitimately sparse payload is served from cache instead
|
||||
// of being mistaken for a miss and forced onto the expensive path on every poll.
|
||||
//
|
||||
// Every collector degrades to empty rather than fatal.
|
||||
// The library suppresses its filesystem reads and redirects stderr on every shell call,
|
||||
// so absent hardware — no GPU, no UPS, no ZFS, no VMs — yields an empty section and an
|
||||
// unrendered card. On a payload this wide that property is what keeps one missing
|
||||
// subsystem from blanking the entire page.
|
||||
//
|
||||
// Remote collection degrades per node, so one dark partner costs its own card and nothing
|
||||
// else.
|
||||
//
|
||||
// Known cost: a cache miss on a host with an unreachable partner pays the remote SSH
|
||||
// timeouts inline. That is why the background writer exists and why the cache window is
|
||||
// long — the miss path is the exception, not the design.
|
||||
//
|
||||
// REQUEST
|
||||
// GET served from the 300s cache when one is present
|
||||
// GET ?live bypass the cache and collect everything fresh
|
||||
//
|
||||
// RESPONSE
|
||||
// A flat object of the keys listed in the assembly below, plus _api_status and ts.
|
||||
//
|
||||
// DEPENDS ON
|
||||
// include/config.php vv_cache_read()
|
||||
// include/common.php raw hardware metrics — system, cpu, mem, net, gpu, disks,
|
||||
// ups, parity, containers, transcodes, remote roll-ups
|
||||
// (loaded transitively through include/monitor.php)
|
||||
// include/monitor.php the "is anything wrong" roll-ups — vv_partner_state(),
|
||||
// vv_fallback_state(), vv_watchdog_summary(),
|
||||
// vv_scripts_status(), vv_rsync_status()
|
||||
// include/unraid_api.php vv_api_data(), vv_api_get_status()
|
||||
// include/vms.php vv_get_vms()
|
||||
// include/docker_folders.php vv_get_docker_folders()
|
||||
// Tools/api_cache_writer.sh writes the cache this endpoint normally serves
|
||||
// ═══════════════════════════════════════════════════════════════════════════════════════════════
|
||||
header('Content-Type: application/json');
|
||||
require_once dirname(__DIR__) . '/include/config.php';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user