Commit Graph
453 Commits
Author SHA1 Message Date
Gmer4Lfe 7e01f6d3db Differentiate API key missing vs API unreachable in monitor banner
unraid_api.php: track key_missing separately from general fallbacks.
  vv_api_data() sets key_missing=true when HOST*_UNRAID_API_KEY is empty.
  vv_api_get_status() includes key_missing in the status payload.

monitor.php: two distinct banner states instead of one orange warning.
  key_missing → subtle dark/grey note: "API key not configured — add
    HOST1_UNRAID_API_KEY in Scheduler → host conf to enable enhanced monitoring"
  key present but unreachable → existing orange ⚠ with fallback list.
  No banner at all when API is working correctly.
2026-05-30 16:26:51 -04:00
Gmer4Lfe 10fc703e57 Add GitHub link, fix Settings page, direct users to setup on install
Plugin/varaverk.plg:
  - Add support="https://github.com/FailedProxy/Varaverk/issues"
  - Install completion log now says "open Varaverk to complete setup"
    with navigation hint — user lands on wizard automatically

Plugin/unraid/VaraverkSettings.page:
  - Fix stale SCRIPTS_DIR default (unraid_scripts → Varaverk)
  - Add GitHub / Issues / Changelog links at bottom of settings page

Plugin/unraid/Varaverk.page:
  - Small "⎋ GitHub" link right-aligned in the tab bar
    links to github.com/FailedProxy/Varaverk in a new tab
2026-05-30 16:22:54 -04:00
Gmer4Lfe d09ea11694 Onboard Step 9: push master.conf to all listed hosts on completion
After Step 8 (arr bootstrap), owner calls vv_push_master_conf() and
vv_push_setup_state() via php -r. SSH is established at this point so
the probe passes and all listed hosts get the authoritative master.conf
immediately — no manual save required.

Skipped if onboard failed, dry-run mode, or php unavailable (with
fallback instruction). Result shown in onboard summary as Step 9.
2026-05-30 16:14:07 -04:00
Gmer4Lfe 0121462576 Graceful degradation before partnership/SSH is set up
Fix 1 — Monitor partner card (common.php + monitor.php):
  vv_remote_hosts_stats() no longer skips hosts with no API key.
  Returns no_api_key:true entry instead. Monitor JS renders
  "API key not configured — complete Onboard to enable" instead
  of a blank space.

Fix 2 — rawconf push not alarming pre-onboard (config.php + scheduler.php):
  Probe failures (Tailscale not found, plugin not installed) now carry
  ready:false. JS treats ready:false results silently — button shows
  "✓ Saved" not "push failed: HOST2" before SSH is set up.
  Only genuine post-onboard failures (ready not false) show as errors.

Fix 3 — Partnership Onboard button (partnership.php):
  Disabled with tooltip when no partner hostname is in master.conf.
  When partner configured but not onboarded, adds explanation note:
  "Onboard will generate your SSH key, exchange it with the partner..."
  No partner configured: "Edit master.conf and set HOST2."
2026-05-30 16:01:44 -04:00
Gmer4Lfe 974e3cf2cf Setup: all hosts land on Partnership after conf setup, not just HOST1 2026-05-30 15:53:52 -04:00
Gmer4Lfe 64f2c89a40 Setup mode: HOST1 lands on Partnership with Onboard highlighted
scheduler.php: after host1.conf save in setup mode, redirect to
  ?tab=partnership&vv_onboard=1 instead of Monitor.
  HOST2+ still redirects to Monitor (they don't manage the partnership).

partnership.php: detects vv_onboard=1 URL param after actions render.
  Adds pulse animation + box-shadow to the Onboard button and scrolls
  it into view. One-shot — gone when user navigates away.
2026-05-30 15:52:41 -04:00
Gmer4Lfe af89258bbd Setup wizard: full first-run flow for HOST1 and HOST2
Varaverk.page: also shows wizard when local host.conf is missing
  (handles master.conf pushed by HOST1 before HOST2 installs plugin).

pages/setup.php: three wizard flows
  - Standard: blank master.conf, fill hostnames, redirect to scheduler
  - Host2/state file: state file detected, pull master.conf from HOST1 via SSH
  - Conf-only: master.conf already filled (was pushed), just create local host.conf

api/setup.php:
  - save action: writes master.conf + host.conf, creates varaverk_setup.db state file,
    redirects to ?tab=scheduler&vv_setup=master.conf
  - pull action: resolves HOST1 Tailscale IP, queries HOST1 SCRIPTS_DIR, SCPs
    master.conf, creates local host.conf, redirects to ?tab=scheduler&vv_setup=hostN.conf

include/config.php: vv_setup_state_read/write/push helpers.
  vv_push_setup_state() pushes varaverk_setup.db to /boot/config/ on all known
  remotes — no plugin-readiness probe needed (flash is always accessible).

api/rawconf.php: calls vv_push_setup_state() alongside master.conf push.

pages/scheduler.php: setup mode via ?vv_setup=<conf> URL param.
  Auto-opens the specified conf file on page load (DOMContentLoaded).
  vvSaveRawConf: in setup mode, skips confirm dialog and forces sequence:
    master.conf save → auto-open hostN.conf
    hostN.conf save → redirect to Monitor (setup complete)
2026-05-30 15:43:04 -04:00
Gmer4Lfe 1e9681a71e Add first-run wizard, host.conf template, fix GitHub URL
Plugin/varaverk.plg: URL updated to github.com/FailedProxy/Varaverk

Configurations/host.conf.template:
  Full host conf structure with HOSTN/hostn placeholders.
  All personal values blank, all sections documented.
  Covers identity, rsync, docker, fallback, media, monitors,
  transcodes, arrs, system watchdog, resource manager.

Varaverk.page: checks if HOST1 is blank before rendering tabs.
  If blank → shows setup wizard, returns early (tabs never render).

pages/setup.php: first-run wizard UI.
  Auto-populates hostname from hostname -s.
  Role selection: primary (HOST1) or partner (HOST2+).
  Partner slot selector for HOST3+.

api/setup.php: handles wizard form POST.
  Writes HOST1/HOST2 (and HOST3+) into master.conf preserving all
  other content. Creates host*.conf from template with HOSTN/hostn
  replaced and SSH key path pre-filled from hostname convention.
  Never overwrites an existing host*.conf.
2026-05-30 15:22:46 -04:00
Gmer4Lfe 6549ed0301 Add .plg install script and master.conf.template
Plugin/varaverk.plg:
- Method="install update": git clone (fresh) or pull (update)
  Validates Unraid, checks array is started via shfs mount, clones
  to SCRIPTS_DIR (read from varaverk.cfg, default /mnt/user/appdata/Varaverk),
  creates Plugin/unraid symlink, inits varaverk.cfg, bootstraps master.conf
  from template on first install.
- Every boot: lightweight boot.sh recreates symlink if missing (no git ops).
- Method="remove": removes web symlink, leaves appdata intact.

Configurations/master.conf.template:
- Full master.conf with personal values blanked: HOST1/HOST2 empty,
  GITEA_REPO_PATH empty, personal container names in profiles cleared,
  FALLBACK_ENABLED=false, CRITICAL/DAILY rsync defaults corrected to true.
  New users fill in HOST1, HOST2, then proceed to partnership setup.
2026-05-30 15:15:40 -04:00
Gmer4Lfe 5ebf1fc96f Add failsafes to vv_push_master_conf before SCPing
Single SSH probe per remote checks all three conditions in one call:
- plugin cfg exists (varaverk.cfg present with SCRIPTS_DIR)
- Configurations/ dir exists at that path
- master.conf already present on remote

Any failure skips that host entirely rather than pushing blind.
Uses the discovered SCRIPTS_DIR as the SCP destination, not ours.
2026-05-30 14:43:37 -04:00
Gmer4Lfe b5d7413d88 Query remote SCRIPTS_DIR before SCPing master.conf
Instead of assuming the remote uses the same appdata path as the local
host, SSH-grep their varaverk.cfg first and SCP to their actual
Configurations/ dir. Falls back to /mnt/user/appdata/Varaverk if the
plugin isn't installed or the file can't be read.
2026-05-30 14:37:47 -04:00
Gmer4Lfe da0c303f22 Push master.conf to all partners immediately on raw-editor save
vv_push_master_conf() in config.php: finds all remote HOST* entries,
resolves Tailscale IPs, SCPs master.conf to each.
rawconf.php calls it after a successful write when file=master.conf.
Scheduler save button shows sync status: "✓ Saved · synced to HOST2"
or "✓ Saved · push failed: HOST2" on error.

Also fix path bug in partnership_transfer.sh — was SCPing to
appdata root instead of Configurations/.
2026-05-30 14:21:02 -04:00
Gmer4Lfe 26f3778786 Remove redundant Scripts dir field from Scheduler tab
VaraverkSettings.page (Settings → Other Settings) now owns SCRIPTS_DIR.
The inline Advanced-mode field and vvSaveSettings() in the Scheduler tab
were a second path to the same write — removed.
2026-05-30 14:06:28 -04:00
gmer4lfe e6a0ab8e64 conf: add FALLBACK_PARTNERSHIP gate vars, remove PLAY_SYNC section 2026-05-30 10:24:56 -04:00
Gmer4Lfe 0fe99cf2a9 rename: appdata/varaverk → appdata/Varaverk (capital V throughout) 2026-05-30 10:22:51 -04:00
Gmer4Lfe 2d5a084d2b fix: GITEA_REPO_PATH = FailedProxy/Varaverk.git 2026-05-30 10:21:26 -04:00
Gmer4Lfe afe5c10679 fix: GITEA_REPO_PATH org — FailedProxy/varaverk not Varaverk/varaverk 2026-05-30 10:18:36 -04:00
Gmer4Lfe 921900b23b rename appdata folder and repo from unraid_scripts to varaverk
- TARGET_DIR, DATA_DIR: /mnt/user/appdata/unraid_scripts → /mnt/user/appdata/varaverk
- GITEA_REPO_PATH: Varaverk/Unraid_Scripts.git → Varaverk/varaverk.git
- DEV_ROOT: .../Development/Unraid_Scripts → .../Development/varaverk
- deploy hook path updated in .claude/settings.json
- All script comments, docs, and manual paths updated throughout
2026-05-30 10:07:03 -04:00
Gmer4Lfe 788c04ce9d play_state_sync: sync across all hosts via Tailscale
Discover all HOST*_TRANSCODE_SERVERS from every configured host.
For remote hosts, rewrite localhost/127.0.0.1 in the URL to their
Tailscale IP (via resolve_tailscale_ip). Unreachable hosts are
warned and skipped — partial sync continues for reachable servers.

Adding a new host needs no script changes — just HOST*_TRANSCODE_SERVERS
in the new host conf.
2026-05-30 00:23:32 -04:00
Gmer4Lfe 1184be3e28 play_state_sync: move to CRITICAL_MAINTENANCE_SCRIPTS (every 30min)
Removed from DAILY_MAINTENANCE_SCRIPTS — critical orch already covers it
at a much tighter cadence. Play state stays in sync within 30 minutes of
any watched/resume activity on either server.
2026-05-30 00:17:54 -04:00
Gmer4Lfe 23062acdac play_state_sync: fix jq combine fallback + detect_hosts; load_config: fix word-split on paths with spaces
play_state_sync.sh:
- Add detect_hosts() call so TRANSCODE_SERVERS alias is populated
- Switch MEDIA_SERVERS → TRANSCODE_SERVERS (correct array name from host*.conf)
- Fix malformed jq fallback in combine step (was {"} now handled with if/else)
- Skip placeholder API keys in _add_server

load_config.sh:
- Replace 'for x in $(ls glob)' with 'while read < <(printf glob | sort)'
  so paths with spaces (e.g. dev workspace) don't get word-split
2026-05-30 00:13:26 -04:00
Gmer4Lfe 26693fd11f Add play_state_sync.sh — sync watched state across Emby + Jellyfin
Syncs played/resume state bidirectionally across all configured Emby
and Jellyfin servers. Newest LastPlayedDate wins; users matched by
name (case-insensitive); unmatched users skipped cleanly.

Matching: IMDb/TMDB for movies, TVDB+s/e for episodes, MusicBrainz
track ID for audio. Also syncs resume positions for partial plays.

Config: PLAY_SYNC_ENABLED, PLAY_SYNC_DAYS (default 90), PLAY_SYNC_TYPES.
Modes: --dry-run, --status, --full (ignore day window), --log.
Wired into DAILY_MAINTENANCE_SCRIPTS after arr cleanup.
2026-05-30 00:02:18 -04:00
Gmer4Lfe ce9748096c Scheduler: extra args input on script rows
- Tools and Custom: args input always visible (translucent at rest, full on hover)
- Orch children: args input hidden when orch is on, shown when orch is off
  (same toggle as the cron field — orch off = standalone mode)
- vvRunJob/vvDryRun: pick up .vv-script-args value, POST as extra_args
- run.php / dryrun.php: accept extra_args, validate against shell metacharacters,
  append to run_job.sh invocation (flows through SCRIPT_ARGS to the script)
- CSS: .vv-script-args — 30% opacity at rest, 100% on hover/focus
2026-05-29 23:56:15 -04:00
Gmer4Lfe d2eb060fe5 docker_prune_images: add --all mode for full orphan cleanup
Default still removes only dangling (untagged) images.
--all removes stopped containers first, then all images not used
by any running container — clears tagged orphan images left behind
by removed or stopped apps.
2026-05-29 23:36:59 -04:00
Gmer4Lfe 86048b32d3 Plugin: common.php library, watchdog expansion, monitor + scheduler improvements
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
2026-05-29 23:33:52 -04:00
Gmer4Lfe 8f05f0d27c Docker tab: full inspect detail — icon, IP, ports, paths per container
- Replace pill view with per-container rows showing full detail
- docker inspect batch call: networks+IPs, port mappings, bind mounts
- Container icon from template XML, name links to WebUI if configured
- Network IP badges (blue), port mapping badges (yellow)
- Bind mount paths shown src→dst, collapsible expand for >3 paths
- Large folders (>7 containers) auto-span full width
- Status badge: RUNNING/STOPPED/PAUSED/EXITED with colour
- Stopped containers dimmed, icons load from template XMLs
2026-05-28 22:48:06 -04:00
Gmer4Lfe 00a8a64c4e Docker tab: own config file, folder.view3 becomes optional sync target
- Primary store moved to /boot/config/plugins/varaverk/docker_folders.json
- No dependency on folder.view3 plugin being installed
- Auto-imports folder.view3 JSON on first run if it exists (one-time bootstrap)
- Mirrors writes to folder.view3 JSON only if that plugin's directory is present
- Toolbar shows '⇄ folder.view3' badge when sync is active
2026-05-28 22:41:10 -04:00
Gmer4Lfe e95fd30e13 Varaverk: Docker tab — folder management with conf + folder.view3 JSON dual-write
- New Docker tab (between Scheduler and Watchdog)
- Reads /boot/config/plugins/folder.view3/docker.json — fully compatible with folder.view3 plugin
- Writes changes to both docker.json AND HOST*_DOCKER_FOLDER_MAP in host*.conf simultaneously
- Edit mode: rename folders (inline input), delete folders, move containers via popover picker, create new folders
- Drift banner: highlights containers where conf desired state doesn't match json actual state
- Sync conf→JSON: apply conf desired state to json (fixes drift after onboard)
- Sync JSON→conf: capture manual json edits back into conf
- Ungrouped section shows all containers not assigned to any folder
- Onboard scripts can read HOST*_DOCKER_FOLDER_MAP to auto-place new containers
2026-05-28 22:39:44 -04:00
Gmer4Lfe fb051b60c1 Varaverk: FallBack + Watchdog tabs; plugin path restructure to Plugin/unraid/
- FallBack tab: per-node tier inventory + active fallback card with duration, tier, handback strikes, running container status
- Watchdog tab: live system health (RAM bar + thresholds, load, uptime, daemon), docker watchdog strikes + skip list + restart history, stability strikes + reboot log, resource pressure alert card, config inventory (mem limits, required, pause/stop lists)
- Swapped partnership/arrs tab order; FallBack between partnership and watchdog
- Plugin source tree moved from Plugin/usr/local/emhttp/plugins/varaverk/ to Plugin/unraid/
- Deployment/ conf templates added
2026-05-28 22:24:50 -04:00
FailedProxy 64d95aa991 conf edit 2026-05-28 20:59:53 -04:00
Gmer4Lfe 446794e41d Varaverk: grid layout tweaks + mobile folder fix
- Move Parity to row 4 (cols 1-2), Scripts to row 2
- GPU card: span 2
- Memory card: proc strip clips with ellipsis instead of overflowing
- Containers & VMs: use JS window.innerWidth check (<=640) for single-column
  folder layout instead of CSS media query — fixes badge alignment on mobile
  where Unraid's viewport doesn't trigger CSS breakpoints reliably
2026-05-26 19:19:22 -04:00
Gmer4Lfe 072c8b720d Varaverk: monitor grid overhaul + Containers & VMs card
Monitor layout (8-col grid):
- Row 1: System | Power | CPU | Memory | Network
- Row 2: Scripts | Partner & Fallback (span 3) | Containers & VMs (span 4)
- Row 3: GPU (span 2) | Transcode (span 2) | Streams (span 4)
- Row 4: Parity (cols 1-2) | Pools (cols 3-4) | Array (cols 5-8)

New Containers & VMs card:
- Reads FolderView3 folders from docker.json; expand/collapse per folder
- VMs listed first (virsh); containers show start/stop/webui/edit actions
- 2-column balanced layout; collapses to 1 column below 900px
- Docker WebUI URLs resolved from dockerMan template XMLs

New files: include/vms.php, include/docker_folders.php, api/docker_action.php, api/snapshot.php
Responsive: explicit grid-column placements reset at 1024px breakpoint
2026-05-26 18:59:19 -04:00
Gmer4Lfe 6078af0dbb Varaverk: arrange mode, folder management, rsync standalone, layout fixes
Scheduler UI:
- Arrange mode: drag scripts between orchs and reorder within arrays; right
  panel shows unassigned script pool; Save Arrangement commits to master.conf
- + Folder: named collapsible subfolders for Custom Scripts stored in schedule.json
- Rsync children: hide Run/Dry Run/Log/location when orch is ON; show standalone
  location + cron controls when orch is OFF; cron only fires when both filled
- Non-conf-managed children (transcode): toggles now show enabled when orch is on
- Right panel height sync: fix ResizeObserver feedback loop via align-self:flex-start
  on left panel and left.offsetHeight in vvFitRight
- How do I use this: updated to cover arrange, folders, rsync standalone, transcode

New API endpoints:
- board.php, clearlock.php, movescript.php, rawconf.php, readscript.php
- reorderarray.php, rsync_standalone.php, savefolders.php

run.php / dryrun.php: accept optional --location= arg for standalone rsync calls
2026-05-25 21:46:12 -04:00
Gmer4Lfe 6b30768853 webgui_watchdog: mark executable 2026-05-24 23:33:39 -04:00
Gmer4Lfe 8e0d68665c Move dangling image prune from docker_update.sh to docker_daily_restart.sh
Restarts create the orphans — prune belongs in the same script immediately
after the restart loop, not in the update script that runs before it.
2026-05-24 23:32:00 -04:00
Gmer4Lfe 83ff9fca5e docker_update: prune dangling images after pull (both normal and remainder modes)
Daily restarts create orphaned images that were never cleaned up.
Added docker image prune -f section matching docker_update_remaining.sh pattern.
Prune runs each cycle so orphans from the previous day's restart are removed daily
rather than waiting for the weekly docker_update_remaining.sh sweep.
2026-05-24 23:14:31 -04:00
Gmer4Lfe 83195ebb9e monthly_maintenance: reschedule to 0 0 15 * * (15th at midnight)
Previously ran daily at 3am with internal self-gating. Now scheduled directly
on the 15th — uptime and interval gates still apply; a skip means next month's 15th.
2026-05-24 23:10:31 -04:00
Gmer4Lfe dfb462a18e Varaverk: suggested cron hints left of every cron input
- vv_script_children() now calls vv_script_suggested_cron() per child,
  adding suggested_cron and suggested_label to each child entry
- Orch rows (non-event) and regular script child rows render a faint
  .vv-cron-hint span to the left of the cron input showing the suggested
  cron from the script's # Schedule: header
- Clicking the hint fills in the cron input (data-cron + onclick)
- Tooltip shows full "suggested_cron — label" string on hover
- .vv-cron-hint: color #444, brightens to #888 on hover
2026-05-24 22:59:33 -04:00
Gmer4Lfe d6cfcaef46 Varaverk: always open Scheduler Information on page load; restore button for last log 2026-05-24 22:51:35 -04:00
Gmer4Lfe eade6072b0 Varaverk: Scheduler Information panel with structured how-it-works sections
- Right panel title: "Suggested Schedules" → "Scheduler Information"
- Removed top hint paragraph; info now lives in the panel itself
- Added three collapsible info sections (open by default) at top of panel:
  Controls — toggle, cron, run, dry run, log, stop, verbose, config
  Orchestrators — enabled/disabled behavior, child cron rules, event triggers
  Children & Advanced — toggle semantics, independent cron, rsync flag badge
- Bullet lists use CSS columns:2 with column-fill:balance for even distribution
- "Suggested Schedules" divider separates info from parsed schedule blocks
- Added vvToggleSug() for DOM-traversal-based accordion (no ID dependency)
2026-05-24 22:47:34 -04:00
Gmer4Lfe cdd2dfc990 Varaverk: rsync flag toggle + stop button
- Rsync/rsync.sh children in Advanced now show as conf_flag type when the
  parent orch controls a *_RSYNC_ENABLED tier flag; toggle writes true/false
  to master.conf instead of comment/uncommenting a SCRIPTS array entry
- Added vv_conf_flag_value() and vv_conf_flag_set() helpers in scheduler.php
- Added api/flag_toggle.php endpoint (validates *_RSYNC_ENABLED pattern)
- Added api/stop.php: kills process group, sweeps stuck locks, updates stat
- vv-flag-badge CSS (amber, monospace) to distinguish from event/script rows
- vvSaveChild() routes conf_flag children to flag_toggle.php unconditionally
- vvApplyOrchState() keeps conf_flag toggle at real flag value; disables when orch off
- vvSaveAll() skips conf_flag children (immediate-save only)
2026-05-24 22:38:33 -04:00
Gmer4Lfe d0d56ed8b9 scheduler: orch-god toggle model — children managed via master.conf
When orch is ON (god mode):
- Children's toggle state is read from master.conf comment status
- Toggling a child comments/uncomments its line in the *_SCRIPTS array
- Child crons are suppressed in vv_cron_rebuild — orch is the sole trigger
- Children not found in any *_SCRIPTS array are shown disabled (read-only)

When orch is OFF:
- All children flip to off; schedule.json updated immediately
- A child with a cron value + enabled toggle gets its own independent cron entry
- A child with no cron does nothing when enabled

New: vv_conf_script_map() — cached per-request scan of master.conf arrays
New: vv_parse_conf_array_full() — includes commented entries (disabled scripts)
New: vv_conf_toggle_script() — comments/uncomments a script line in master.conf
New: api/conf_toggle.php — endpoint for child toggle → master.conf write
2026-05-24 22:24:14 -04:00
Gmer4Lfe 3186097941 scheduler: revert legend grid — restore original hint paragraph 2026-05-24 22:06:48 -04:00
Gmer4Lfe 4832dd8d4e scheduler: replace hint paragraph with compact 3-column legend grid 2026-05-24 21:56:27 -04:00
Gmer4Lfe 655c520ae8 scheduler: add Array Starting / Array Stopping event triggers
Two hardcoded event-triggered entries appear at the top of the scheduler
(array_started.sh / array_stopping.sh). They show an  Array Start /
 Array Stop badge instead of a cron field and are enabled/disabled via
the normal toggle.

Static event scripts fire them via Unraid's event system:
- event/disks_mounted/array_start_jobs  → runs in background (non-blocking)
- event/disks_unmounting/array_stop_jobs → runs foreground (blocks until done)

vv_cron_rebuild() skips @array_* entries so they never land in the cron file.
Scripts executed on each event are managed in master.conf via
ARRAY_START_SCRIPTS and ARRAY_STOP_SCRIPTS arrays.
2026-05-24 21:54:13 -04:00
Gmer4Lfe 1540c62d3a scheduler: smart auto-scroll replaces separate scroll lock checkbox; lidarr: allow single-seed candidates
Auto Scroll now pauses automatically when user scrolls up and resumes
when they reach the bottom — no separate Scroll Lock needed.

Lidarr discovery no longer hard-skips single-seed candidates; they
score low on breadth but can still reach threshold on merit.
2026-05-24 21:40:03 -04:00
Gmer4Lfe 253d5bf2e1 fix(varaverk): remove legacy /etc/cron.d/varaverk on cron rebuild
Before update_cron was wired in, the plugin wrote directly to
/etc/cron.d/varaverk. That file persisted after the migration and
caused duplicate job firing (two watchdog instances at :00/:15/:30/:45).
The second instance hit the lock, exited with warn, and overwrote the
stat file — killing the running indicator while the first was still live.

vv_cron_rebuild() now unlinks the legacy file after every update_cron
call. Since rebuild_cron (boot event) calls vv_cron_rebuild(), the
cleanup runs on every reboot and every schedule save.
2026-05-24 21:27:38 -04:00
Gmer4Lfe bcb1956bbe feat(varaverk): append logs per run with timestamp separator
run_job.sh was overwriting the log on every cron fire, making it
impossible to see run history. Switch to append mode, print a
── YYYY-MM-DD HH:MM:SS ── separator before each run, and trim to
the last 1000 lines after each run to keep logs bounded.
2026-05-24 21:12:28 -04:00
gmer4lfe 7a61a56ee1 fix(common): prepend /usr/local/sbin to PATH for cron compatibility
Cron runs with PATH=/usr/bin:/bin, which omits /usr/local/sbin where
tailscale (and other Unraid tools) live. resolve_remote_ip silently got
empty results from both tailscale calls, failing all 3 retry attempts
every scheduled run. Export the full path at source time so all scripts
find tailscale regardless of how they're invoked.
2026-05-24 21:08:39 -04:00
gmer4lfe fc1fd27a3f fix(common): lock registry prevents EXIT trap overwrite orphaning locks
Scripts calling acquire_lock followed by acquire_rsync_lock (rsync.sh)
or a custom EXIT trap (resource_watchdog.sh) would overwrite the lock
release trap, leaving the first lock file behind on exit.

Replace per-acquire trap with a _LOCK_FILES registry. _register_lock()
appends each lock file to the array and sets a single _release_all_locks
trap. All acquired locks release together on exit regardless of how many
traps are subsequently set or overwritten.

resource_watchdog.sh: chain _release_all_locks into both its custom trap
and the state-persisted disarm path so the lock releases in all exit paths.
2026-05-24 21:02:59 -04:00