dcron uses the filename in /etc/cron.d/ as the username, so a file named
'varaverk' ran jobs as a non-existent user and was silently ignored.
Switch to writing /boot/config/plugins/varaverk/varaverk.cron and calling
update_cron (which merges all plugin .cron files into /etc/cron.d/root).
In dev mode (no varaverk.plg registered), fall back to injecting our entries
directly into the live root crontab via crontab -c /etc/cron.d -.
run_job.sh: new wrapper called by scheduler cron for every job.
Writes /var/log/varaverk/<id>.json (status/start/end/exit/pid)
and /var/log/varaverk/<id>.log (latest run output, overwritten).
Maps exit 0→ok, 1→warn, 2+→error so watchdog "took action" runs
show warn not error.
scheduler: cron now calls bash run_job.sh instead of inline bash -c.
Added vv_job_stat_path(). LOG_DIR moved to config.php (shared).
monitor: vv_scripts_status() now reads /var/log/varaverk/*.json and
*/*.json — no User Scripts tmpScripts dependency at all.
Stale running detection via /proc/<pid> check.
Returns error_count in addition to running/ok/warn counts.
pages/monitor.php: added error pill (red ✗), error icon/color in
list, duration shown next to age for each script entry.
log() is gated on ENABLE_LOGGING — silent on normal runs. Healthy
confirmations (All healthy, Network healthy, Storage healthy, WebGUI
healthy) were invisible, making banners appear with nothing after them.
Switched all four to plain echo so they show every cycle.
All watchdog scripts now open with a consistent echo banner:
━━━ <icon> <Name> Watchdog — <timestamp> ━━━
Previously network and storage used a quiet log() line (no separator),
and stability_watchdog used warn() which made every run show ⚠️.
Also: network_watchdog now logs "Network healthy ✅" on clean exit,
and stability_watchdog's reboot-trigger block now says "Stability"
instead of the old "System Watchdog" label.
network_watchdog: Tailscale JSON uses "BackendState": "Running" (with space)
but grep pattern matched "BackendState":"Running" (no space) — always failed.
Switched to grep -qE with \s* to handle both forms.
system_watchdog: add echo banner at run start so its output is visually
separated from docker_watchdog in orchestrator logs. Previously appeared
as a continuation of the docker section since docker_watchdog has a banner
but system_watchdog did not.
Layout:
- Switch from three flex rows to single CSS grid (repeat(8,1fr)) — eliminates
gap-count discrepancy between rows; span 1/2/4/8 cards are now pixel-identical
across all rows regardless of how many cards share the row
New cards:
- Scripts card: last-run status (ok/warn/running/unknown), clickable filter pills,
7-row scroll, flex:1 matching Power/Parity
- Streams card: live per-second progress counters, color-coded play buttons
(blue=live, orange=transcoding, green=direct, yellow=paused), server badges
with counts, left-fill column layout (3 per col)
- Transcode card: NVMe indicator, active session count + scrollable list,
session rows with server icon + title + type + method
Dynamic thresholds:
- vv_disk_thresholds() reads /boot/config/plugins/dynamix/dynamix.cfg
- Disk utilization bars: green/orange/red based on warning/critical settings
- Temperature colors: hot/max for HDD, hotssd/maxssd for SSD/NVMe
- Thresholds update every poll cycle; changing Unraid settings takes effect automatically
Other:
- SSD path detection uses findmnt FSTYPE to exclude tmpfs/ramfs (fixes RAM
being reported as SSD transcode target)
- varaverk.css h3: add white-space:normal + overflow:hidden to neutralise
any Unraid global h3 styles that could force card width
- network_watchdog: remove ISSUES++ for Tailscale — it's notify-only by
design, no restart possible; cascading to system watchdog exit 1 was noise
- docker_watchdog: move banner to top of cycle so body errors appear under
the correct section header, not visually inside Resource Manager output
- CPU/GPU cards: flex-column so body div takes remaining height
- CPU canvas: flex:1 + min-height:36px instead of fixed 36px
- GPU: add vvGpuHistory + canvas (purple, same style as CPU); canvas flex:1
stretches to fill whatever space the row's tallest card leaves over
- External IP: switch from DDNS domain lookup to curl ifconfig.me with 5-min
cache; DDNS approach broke because host detection uses HOST1_NAME but conf
has HOST1, so domain was never resolved
- Tailscale IP: switch from hardcoded tailscale0 iface to `tailscale ip -4`;
interface name varies (tailscale0, tailscale1) across kernels/installs
media.php: Emby/Jellyfin/Plex session poller for Streams card
confform.php: conf file form helpers for Config tab
script.php: per-script run/log API endpoint for Scheduler tab
vv_network_stats() calls vv_conf_vars() and vv_detect_host() which are defined in
config.php. monitor.php had no require for it, causing a PHP fatal error on every
poll → empty JSON → all monitor cards stuck on "Loading...".
Monitor tab:
- CPU card: per-core bars (freq-colored), overall usage bar, rolling history chart
- Memory card: breakdown by system/VM/ZFS/Docker/free with progress bars
- Network card: LAN + ext + Tailscale IP display, live RX/TX chart with auto-scale
- Streams card: Emby/Jellyfin/Plex sessions with playback bar and server badges
- GPU card: adds power draw, encode%, decode% meters
- Transcode card: ramdisk vs SSD location pill, session count, flip history
- Canvas chart helpers: vvDrawChart, vvDrawNetChart, vvMeter, vvFmtBps, vvFmtGib
api/monitor.php: adds cpu, mem, net to response payload
- Add .vv-save-check span to each job row (orchestrators + children)
- CSS: fade-in-then-out animation (visible 1.2s, fades over 2s)
- vvFlashSaved(job): triggers the checkmark animation on a specific row
- vvFlashStatus(el, msg, ok): shows timed status text (was called but missing)
- vvSaveJob: now shows per-job checkmark on successful save
- vvSaveAll: shows checkmark on each job as its response arrives, plus
global "✓ All saved" / "✗ Some failed" status text below the button
Unraid's system crond is dcron (dillon's cron daemon 4.5), which reads
/etc/cron.d/ for system crontabs WITHOUT a username field, and refuses
to execute files that are group- or world-writable.
vv_cron_rebuild() was writing "SCHED root bash ..." (with username field)
and leaving the file world-writable (666), so dcron silently ignored every
entry. Fixed:
- Remove CRON_USER from the generated cron line format
- chmod 0600 the cron file after writing it
- Change suggestion title color from bright green (#6fcf97) to soft grey-blue (#7a9eb5)
- Fix vv_parse_user_script_template() block-detection regex — $ end-anchor
failed on lines ending with multibyte U+2500 ─ chars; removed anchor so
parser now returns all 22 blocks from user_script_plug-in.sh
- Cron and Advanced button vertically aligned in their respective rows
- Verbose checkbox next to Log button — saves immediately, persists to schedule.json
- --log flag injected into cron lines, manual Run, and Dry Run when verbose enabled
- Coffee report rewritten as lean orchestrator over COFFEE_REPORT_SCRIPTS array
- COFFEE_REPORT_SCRIPTS added to master.conf (7 Sunday monitor scripts)
- Scheduler Advanced tab auto-discovers children via existing array detection
Cron input now sits right of the script label in the same row.
Below each row: one-line description pulled live from the script header
(PURPOSE block or first meaningful comment line) — updates whenever
scripts are edited, no plugin changes needed.
Scripts list on left, persistent log panel on right. On screens ≤880px
falls back to stacked single-column. Right panel stays open until page
refresh or another selection. Running dot pulses green on the job row
and in the log header while script executes, clears when log goes stale.
All fetch() POSTs now send application/x-www-form-urlencoded with the
page-injected csrf_token, satisfying unRAID's auto_prepend CSRF check.
All PHP API handlers switched from php://input JSON to $_POST.
Also adds Dry Run button (orange, between Run and Log) that sets
DRY_RUN=1 in the script environment before executing.
- Run button (blue) fires script immediately, opens log panel;
stamps log with manual run timestamp before exec
- Save moved to card footer — one button saves all cron expressions
for the orchestrator and all its children at once
- Toggle still auto-saves immediately on flip (enable/disable is instant)
- Removed onblur from cron inputs — cron only saves on explicit Save
- api/run.php: validates id, appends timestamp, execs script in background
- Per-job log files replace single jobs.log: each script writes to
/var/log/varaverk/<Category>/<script>.log mirroring the job ID
- api/log.php: serves last 200 lines of a job's log file with mtime
timestamp; supports POST ?clear=1 to truncate
- Scheduler page redesigned as full-width cards (one per orchestrator)
with Save + Log buttons; Log toggles an inline panel that polls
every 3 seconds and auto-scrolls — same pattern as unRAID User Scripts
- Children shown under Advanced with identical per-job log panels
- CSS: vv-sched-card, vv-log-panel, vv-log-pre, vv-btn-sm
Non-greedy (.*?) stopped at the first ) found, which could be inside
a comment like '# gracefully stop fallback (not caught by ...)'.
Anchoring the closing paren to start-of-line (^\s*\)) ensures it only
matches the array's actual closing paren, not ) inside comment text.