Commit Graph
74 Commits
Author SHA1 Message Date
Gmer4Lfe a46317de18 Make tailscale removal opt-in, since it depends on a key that expires and no-ops silently once it has 2026-08-17 04:49:32 -04:00
Gmer4Lfe 32355e0219 Record the tailscale grace period as a deadline instead of sleeping six hours inside the offboard 2026-08-17 04:46:01 -04:00
Gmer4Lfe 2cbc06a683 Show a launched job's progress, stop a refused rerun from overwriting the live record, and label deployed containers so Unraid owns them 2026-08-17 04:26:32 -04:00
Gmer4Lfe cce1e25c2b Let a non-blocking checklist item be dismissed with a recorded decision, and run discovery on the mirror once there is something to discover 2026-08-16 21:56:00 -04:00
Gmer4Lfe 5bdf3bff60 Report each teardown and setup step from what it did, not from whether it was attempted 2026-08-16 21:46:26 -04:00
Gmer4Lfe 65516ea3ac Report the Tailscale device as removed only when it was, instead of whenever the toggle was on 2026-08-16 21:38:03 -04:00
Gmer4Lfe 27989d066e Disarm on offboard every sync gate onboard arms, with the same helper, so the two are one operation in both directions 2026-08-16 21:36:46 -04:00
Gmer4Lfe 662f4f0d53 Create the network and cache partner confs in phase 1, where SSH already works and no plugin is needed on the far side 2026-08-16 21:13:46 -04:00
Gmer4Lfe a02b918ff9 Make the cancel actually remove the key it says it removed, instead of erroring into a swallowed stderr 2026-08-16 21:03:54 -04:00
Gmer4Lfe 23825a824d Create the networks our own pushed templates name, instead of trusting a fresh mirror to have uncommented them 2026-08-16 20:50:10 -04:00
Gmer4Lfe 7ed0f5c23b Send the webhook setup to the path the partner actually uses, and arm the sync gates before the seed that depends on them 2026-08-16 20:32:14 -04:00
Gmer4Lfe f363c6cd55 Match the trigger failure patterns before the success one, since the failures echo a path back 2026-08-16 20:26:46 -04:00
Gmer4Lfe c8a6f58007 Launch owner-side Phase 2 through run_job.sh so it leaves a job record, and only claim it started once one exists 2026-08-16 20:25:54 -04:00
Gmer4Lfe 93cdbaac57 Give the mirror the terminal step its half of phase 1 actually needs, instead of a button that cannot answer a password prompt 2026-08-16 20:16:17 -04:00
Gmer4Lfe 4f95cc6d13 Deliver master.conf to a node that has no Varaverk on it yet, which is the node that needs it
Phase 1 exists to hand the partner its identity before the install, but the push refused any
host without varaverk.cfg — so the conf could only ever reach a node that no longer needed it
to be told who it was. It now resolves the remote's conf directory across both install layouts
and creates the internal one when neither exists.
2026-08-16 16:14:23 -04:00
Gmer4Lfe 1d4dc44668 Name HOST2 by the hostname the key derivation actually uses, not its Tailscale spelling 2026-08-16 13:07:10 -04:00
Gmer4Lfe 0fe3435033 Let the conf push seed a node that has no master.conf yet, which is the node it exists to seed 2026-08-16 13:05:04 -04:00
Gmer4Lfe 6d9c856514 Open the sync gates when a partnership actually completes, instead of leaving them shut for ever 2026-08-16 12:51:24 -04:00
Gmer4Lfe 7a8fbbe06a Correct stale references across the remaining folder docs
Three renamed or dissolved names were still cited, and three scheduled scripts had no
entry in their folder's table.
2026-08-01 23:07:50 -04:00
Gmer4Lfe c377ddfcca Complete the header template across Partnership, Kernel, Deployment and Plugin
Finishes the pass: every script now documents its safeguards, and the deliberate absences
in the sourced libraries are recorded so they are not "corrected" later.
2026-08-01 22:44:23 -04:00
Gmer4Lfe 5c4f8db497 Flock the offline counter in partnership --check
It is a read-modify-write, so overlapping cycles lost increments and pushed the
auto-offboard threshold past its configured window.
2026-08-01 22:44:23 -04:00
Gmer4Lfe 6623d1e776 Fix dead/incorrect vars and consolidate duplicated logic into common.sh
Codebase-wide audit pass: fixed real bugs (SSH hangs missing BatchMode,
local-outside-function no-ops, variable name collisions, a truncated
ratio calc, wrong state-dir path, DARK vs NO_INTERNET drift, and more),
then pulled logic that was duplicated across multiple scripts — arr
cleanup safety gates, docker restart ordering, container maintenance
stop/restart, watchdog state-file helpers, partnership role resolution,
cert expiry checks, remote node discovery, and TMDB discovery scoring —
into common.sh so each now has a single implementation.
2026-07-03 23:52:33 -04:00
Gmer4Lfe 69189bbf18 Fix dead-variable and exit-code bugs found in codebase-wide audit
Same audit as the orchestrator standardization pass (2a062e5), extended to
every remaining script. Found the same class of bug independently recurring:
ramdisk_stop.sh checked $LOG (nothing assigns it, should be $ENABLE_LOGGING),
partnership_onboard.sh checked $LOG_MODE (same issue), emby_session_report.sh
checked $TRANSCODE_PCT which was never computed so the high-transcode alert
could never fire, and storage_migrate.sh never called detect_hosts() so
$MY_ID was empty, silently breaking the post-migration host*.conf update.
partnership_manager.sh used `local` at top-level script scope (invalid outside
a function) and had two master.conf path references missing "Configurations/".

Along the way: several scripts (share_setup.sh, conf_sync.sh,
downloaders_reset.sh, transcode_cleanup.sh, transcode_manager.sh,
remote_arr_cache_writer.sh, upgrade_webhook_handler.sh) had no explicit
trailing exit code, so they always reported success regardless of real
failures. play_state_sync.sh was missing the partnership gate its own header
documented, so remote play-state sync ran even with PARTNERSHIP_ENABLED=false;
it also always exited 0 on sync errors. arr_profile_enforcer.sh and
webhook_setup.sh hand-rolled their own flag parsing instead of common.sh's
parse_args, so --log silently did nothing on either.

system_watchdog.sh was itself an un-standardized mini-orchestrator — converted
to the shared run_orch_child()/JOB_PASS/JOB_FAIL pattern, added the missing
failure notification, and fixed dry-run to pass --dry-run down to children
instead of skipping them outright. Also fixed a stale webgui_watchdog.sh path
in master.conf.template that would break system_watchdog.sh on any fresh
install.

Closed a sibling-drift gap: radarr_cleanup.sh and sonarr_cleanup.sh were
missing lidarr_cleanup.sh's tracked-count percentage-drop safety gate and its
"not configured on this host, skip cleanly" guard — both now match Lidarr's
7-gate model.
2026-07-03 17:35:30 -04:00
Gmer4Lfe b314aa4aff fix monitor disk used space underreported for spun-down disks
Unraid API returns fsUsed=0 when a disk's filesystem is unmounted (spun
down). disks.ini keeps the last-known value in KB even after spindown —
use it as fallback when isSpinning=false and fsUsed=0. Also remove the
mounted-only guard in the ini fallback path (vv_disk_entry) for the same
reason. Stale comments in user_script_plug-in.sh and partnership_manager.sh
also cleaned up.
2026-06-27 23:08:51 -04:00
Gmer4Lfe b4bc9267e9 Move arr stack scripts from Media/ to Arrs_Stack/
Media/ now holds only media-level scripts (cleaner, permissions, play_state_sync).
All arr management scripts (cleanup, discovery, sync, webhooks, release fixer) live in Arrs_Stack/.
2026-06-27 18:39:33 -04:00
Gmer4Lfe 0401d872e4 Script audit: fix stale names, header mismatches, HOST1-hardcoded path maps in lidarr scripts 2026-06-27 13:42:06 -04:00
Gmer4Lfe 638aba20c0 Rename Lldap-Gmer4Lfe to Lldap and guard local containers in cleanup 2026-06-26 17:56:20 -04:00
Gmer4Lfe bf3e7cc2c4 Storage-mode awareness pass + doc update for System_Essentials through Partnership
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).
2026-06-19 19:32:39 -04:00
Gmer4Lfe 28d434b76c Propagate new fallback model to all remaining script references
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.
2026-06-19 17:49:26 -04:00
Gmer4Lfe f42ecc8464 Add docker actions, arr profile enforcer, monitor caching, and web file symlink
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.
2026-06-19 11:09:40 -04:00
Gmer4Lfe 978a5865a7 Add webhook setup, media seed, and listener start to onboarding (steps 9b-9d) 2026-06-14 21:40:25 -04:00
Gmer4Lfe 5a7d5b5005 Add share_setup.sh — create missing mirror shares during onboarding (pool-aware, idempotent) 2026-06-14 14:53:51 -04:00
Gmer4Lfe 3964f6fb46 audit echo vs log across all scripts — outcomes always visible, verbose for per-item loops 2026-06-14 12:40:15 -04:00
Gmer4Lfe fdef61cc25 Fix container updates: rebuild on new image, consolidate update scripts
Weekly sync window was pulling images but using docker start after rsync,
which ignores the new digest. Containers in the emby/critical-data profiles
(Emby, Mariadb, Redis) never actually landed on updated images.

docker_update_remaining.sh merged into docker_update.sh --remainder, which
already had better exclusion logic. Added WEEKLY_REMAINING_UPDATES toggle
and WEEKLY_RESTART_CONTAINERS exclusion to remainder mode.

Onboard now runs docker_network_connect.sh on mirror before deploying stacks.
2026-06-14 10:58:19 -04:00
Gmer4Lfe ba3eed39e3 Sync READMEs and manuals to current script headers
Fix discrepancies found by auditing docs against headers:
- stability_watchdog.sh: wrong variable name (STRIKES → STRIKE_LIMIT) and wrong default (2hr → 12hr) in header
- Watchdogs manual: REBOOT_WINDOW_HRS example value was 2, should be 12
- Transcodes README: transcode_cleanup/manager table said "Every 3 min", should be "Every 7 minutes"
- Tools manual: fallback_state_reset.sh still marked "not yet built" — rewrite section to reflect current script
- Tools manual: claude_startup --setup flag doesn't exist; modes were inverted — fix and add --launch
- Tools README + manual: add docker_prune_images.sh (existed but undocumented)
- Tools manual: add play_state_sync.sh --full to flag reference
- Orchestrators README: arrs_failed_stalled_recovery runs via intermediate_sync (every 4hr), not standalone every 6hr
- Plugin README: add build.sh to scripts table
- Partnership README + manual: add partnership_transfer.sh and onboard_cancel.sh to script tables and flag reference
2026-06-14 02:01:27 -04:00
Gmer4Lfe 181114aed5 Header/code audit fixes across all core scripts
Behavior fixes:
- docker_daily_restart.sh: implement RESTART_VERIFY_WAIT sleep before
  verify_running() — variable was logged as config but never applied
- cert_monitor.sh: --log now shows expiry date and days remaining for
  healthy domains in the per-domain summary; problems always show details

Header corrections:
- downloaders_reset.sh: fix frequency contradiction (15 min → 30 min)
- lidarr_cleanup.sh: Emby scan triggers on actual deletions, not every run
- ssh_setup.sh: document --local-only flag in USAGE section
- zfs_memory_snapshot.sh: clarify dry-run skips log write in PURPOSE
- ramdisk_stop.sh / ramdisk_setup.sh: document TRANSCODE_STATE_FILE var
- smart_long_test.sh: remove SMART_TEMP_WARN/CRIT — not used in code
2026-06-14 01:40:35 -04:00
Gmer4Lfe b4d6866f40 Polish before first GitHub push: consistent adapter usage and naming
stability_watchdog.sh mover check now uses platform_is_mover_running()
instead of raw pgrep, matching server_reboot.sh.

check_unraid_version_parity() renamed to check_os_version_parity() —
the function internals were already platform-neutral after the adapter
refactor; the name was the last Unraid artifact.
2026-06-14 01:30:16 -04:00
Gmer4Lfe ee5a07be1c Remove remaining OS-specific hardcodes from core scripts
OS version reads now go through platform_get_os_version() and
platform_os_version_probe_cmd() instead of grepping /etc/unraid-version directly.

STATE_DIR fallbacks to /boot/config removed — STATE_DIR is always set by
load_config.sh and the fallback encoded a platform-specific path.

Setup DB path references use platform_setup_db_path() instead of the
VARAVERK_SETUP_FILE/-/boot/config compound fallback.

DOCKER_APPDATA_BASE default removed from arr_sync.sh — the adapter sets it.
2026-06-14 01:22:02 -04:00
Gmer4Lfe 3c900ae5c1 Resolve remote storage path from host*.conf for true cross-platform SSH support
detect_hosts() now sets REMOTE_STORAGE_PATH from HOST*_STORAGE_PATH in the
remote's conf instead of calling platform_storage_path() locally. SSH commands
that check the remote's storage (check_remote_array, check_remote_disks,
check_both_healthy) use $REMOTE_STORAGE_PATH so they work correctly when the
remote is a different platform with a different storage root.
2026-06-14 01:09:53 -04:00
Gmer4Lfe 27bfc21cb0 Platform-agnostic refactor: eliminate OS-specific hardcodes from core scripts
All bash scripts are now platform-neutral. Unraid-specific paths, commands,
and service checks moved to Plugin/unraid/adapter.sh. Core scripts call
platform_*() functions exclusively — no direct OS paths in runtime logic.

New adapter functions: platform_storage_path, platform_webui_install_path,
platform_scripts_dir_probe_cmd, platform_setup_db_path, platform_storage_healthy,
platform_is_service_enabled, platform_get_temp_thresholds, platform_disk_states_path,
platform_rebuild_container, platform_push_conf, platform_push_setup_state,
platform_get_templates_dir, platform_send_os_notification.

Partnership services stack (Emby/Jellyfin/Seerr/SeerrFin) added as third
onboarding stack alongside auth and arr stacks.
2026-06-14 00:59:19 -04:00
Gmer4Lfe 9c3ace95a7 Auth stack certs tab, arrs db fallbacks, cert monitor cache, conf parser fix
- Auth stack: fold cert monitor into Auth Stack page as fourth tab (Certs);
  remove standalone cert page and top-level tab
- cert_monitor.sh: write JSON status cache to State_Files/cert_status.json
  after each run; expose per-domain days/expiry via _CERT_DAYS/_CERT_EXPIRY globals
- api/cert.php: new — serves cached cert status; falls back to configured
  domains as UNKN when no cache exists; POST action=run triggers live check
- arrs db fallbacks: vv_arr_cleanup_stats/discovery_stats/recovery_stats now
  read from data/*.db files when log JSON files don't yet exist
- config.php vv_conf_vars(): unescape bash \$ → $ so passwords with dollar
  signs read correctly from conf files
- host1.conf: fill in HOST1_NPM_USER/PASS and HOST1_LLDAP_USER/PASS
- Partnership adapter pattern: Unraid-specific container logic extracted to
  Plugin/unraid/Partnership/; platform-agnostic structure stays in Partnership/
- First-run wizard: uniform multi-step flow for all hosts; HOST2 pull moved
  to checklist; auto SSH keygen and API key creation on save
- api/checklist.php: live setup checklist with pull_master action
- Fullscreen toggle: hide Unraid header/menu; state persists via localStorage
2026-06-05 23:17:30 -04:00
Gmer4Lfe 369a9e6c19 Platform adapter: rename System_Essentials, add Plugin/unraid/adapter.sh, wire call sites
- Rename unRAID_Essentials/ → System_Essentials/ (git detects as rename)
- Add Plugin/unraid/adapter.sh: 13 platform_*() functions providing OS-agnostic API
  for storage health, service management, mover, user scripts, notifications,
  disk temps, and platform command validation
- Update load_config.sh: detect PLATFORM (unraid/truenas/unknown), export SCRIPTS_DIR,
  auto-source Plugin/$PLATFORM/adapter.sh after common.sh
- Wire all call sites: replace direct rc.d, pgrep/pkill, var.ini, dynamix.cfg,
  disks.ini, and validate_unraid_cmd calls with platform_*() functions across
  watchdogs, orchestrators, and System_Essentials scripts
- Update all documentation: rename refs, update webgui escalation logic,
  add platform adapter section to Plugin README, update main README with
  portability vision and corrected self-healing stack description
2026-06-04 18:14:34 -04:00
Gmer4Lfe 0cb429222a Add storage mode migration: internal NVMe vs USB flash, Settings tab, fix hardcoded /boot/ paths 2026-06-03 17:40:35 -04:00
Gmer4Lfe cb7d7a688d rename: failover → fallback throughout codebase — this system is Fallback, state is FALLBACK; preserve conventional failover comparisons 2026-06-01 20:04:17 -04:00
Gmer4LfeandClaude Sonnet 4.6 fb0530deba Consolidate all paths to plugin flash dir, fix watchdog 7.3 triggers
- 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>
2026-05-31 13:30:20 -04:00
Gmer4Lfe 9191a54637 Fix ssh_setup.sh: HOST_CONF path missing Configurations/ subdirectory
Was looking for host1.conf at SCRIPTS_ROOT/host1.conf instead of
SCRIPTS_ROOT/Configurations/host1.conf — causing the 'host1.conf not found'
warning and leaving HOST1_SSH_KEY unwritten after key generation.
2026-05-30 21:31:46 -04:00
Gmer4Lfe 2989cefb79 Redesign Cancel/Delete Keys in Partnership Actions
onboard_cancel.sh:
- --direction=h1 (default): remove HOST1's key from HOST2 + delete local pair
- --direction=h2: remove HOST2's key from HOST1's authorized_keys (by hostname match)
- --direction=both: both directions (used by Cancel button at phase 1)

pages/partnership.php:
- Cancel button: phase 1 only, runs --direction=both (full undo)
- Delete Keys (🗑): available at all phases, expands inline panel showing
  HOST1→HOST2 and HOST2→HOST1 as separate removal buttons with descriptions
- _vvDeleteKeys toggle state persists across polls alongside _vvOnboarding
- vvPtShowDeleteKeys / vvPtHideDeleteKeys top-level toggle fns
- vvPtDeleteH1 / vvPtDeleteH2 targeted removal fns
2026-05-30 21:29:20 -04:00
Gmer4Lfe 1956b6b068 Fix: local keyword outside function in --local-only block
flag_key was declared with 'local' at script top level, which is only
valid inside bash functions. This left flag_key empty, writing '=true'
(malformed) to setup.db instead of 'HOST1_LOCAL_DONE=true'.
Changed to a plain variable assignment.
2026-05-30 21:20:56 -04:00
Gmer4Lfe 95fd38799d Phase 1: resilient SSH handling + Push Conf button
partnership_onboard.sh (--phase1-only):
- Test if SSH already works first (BatchMode) — skip ssh-copy-id if yes
- If ssh-copy-id fails (no TTY in background): soft-fail, generate key locally,
  print pubkey for manual install, write HOST2_KEY_READY=true, run local setup
- Only skip conf push if SSH truly unavailable; otherwise proceeds normally
- Exit 0 with clear manual-step instructions instead of hard failure

include/partnership.php:
- Read HOST2_KEY_READY from setup.db; expose as key_ready on remote nodes

pages/partnership.php:
- Node card: amber "Key generated · install on HOST2 then Push Conf" badge
  when key_ready=true and phase=0
- "Push Conf (key installed)" button appears when key_ready=true — runs
  --phase1-only --skip-ssh (assumes user manually did ssh-copy-id)
- vvPtPushConf() top-level function
2026-05-30 20:27:30 -04:00
Gmer4Lfe 7d4994f317 Local onboard: set PARTNERSHIP_ENABLED=true in master.conf + push
When HOST1 completes its local setup (--onboard --local-only), enable the
partnership in master.conf so sync scripts start functioning immediately.
Pushes the updated master.conf to all listed hosts via vv_push_master_conf().
2026-05-30 20:00:54 -04:00