Drives on a headless Jellyfin box ran hot 24/7: NAS-class drives (WD
Red, IronWolf) ship with no idle timer at all. v0.1.2 stopped tuistream
from keeping them awake; this makes them actually go to sleep.
Spin-down is a DEFAULT, not a feature: when the inventory shows
spinning media drives, the TUI silently installs/syncs the mechanism
and flashes what it did. [s] on Setup is the opt-OUT, remembered via
/etc/tuistream/spindown-off so the default never fights the user.
The mechanism is a tiny systemd service (tuistream --spindown-watch)
that samples /proc/diskstats and issues `hdparm -y` to any target drive
idle past 3 minutes. We deliberately do NOT use the drive's own standby
timer (hdparm -S): the 10TB helium WD Reds advertise it and then ignore
it — verified on real hardware (fresh -S 36, zero I/O, four minutes,
still active/idle). Forcing standby from outside works on everything.
An rc shipped the udev+hdparm -S approach; the plans clean its rule up.
Safety: targets are spinning (sysfs rotational), top-level, real disks,
never a system disk — same classifier the rest of Setup trusts. The
watcher's own probes can't disturb drives: /proc/diskstats and sysfs are
kernel memory, and hdparm -C (CHECK POWER MODE) doesn't wake or reset
anything. The unit's ExecStart points at the running binary and the
auto-sync rewrites it when the content goes stale (e.g. binary moved
from a dev path to /usr/local/bin).
hdparm joins the dependency pre-flight. Verified end-to-end on moviebox
(2x WD Red 10TB SATA + IronWolf 10TB USB): auto-applied on launch, all
three drives reached standby after 3 idle minutes, Monitor shows them
as "asleep" without waking them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Monitor tick ran smartctl against every physical disk every 5
seconds, regardless of which tab was visible — and smartctl's default
behaviour is to spin up a drive in standby to read its attributes. Net
effect: drives could never spin down and ran (hot) 24/7 while the TUI
was open.
Three fixes:
- smartctl now runs with -n standby: a sleeping drive is never woken
for a health probe. It's reported as a new Standby state and shown
as "asleep" in the SMART table — a good sign, not a missing reading.
- Health probes only run while the Monitor tab is visible. The tick
always re-arms, but Setup/Manage now cost zero disk activity.
Switching to Monitor (or pressing r on it) fires an immediate
refresh so the snapshot is never stale.
- SMART moved to its own 60s cadence. The 5s tick keeps the cheap
probes (statfs, /proc, systemd); disk rows are cached between SMART
probes so the table doesn't flicker. lastSmart is stamped at issue
time so a slow USB bridge can't double up probes.
Verified on moviebox (3x 10TB spinning drives) with a counting shim
around smartctl: 0 calls while on Setup, immediate probe on entering
Monitor, then exactly one batch per 60s.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Every fstab writer deduped on the exact line, so a stale entry for the
same mount point (e.g. the UUID of a pool that was since recreated)
survived forever. systemd-fstab-generator only creates one mount unit
per mount point and the FIRST line wins — if that line is stale, the
pool never mounts at boot, shows up as detached, and the user has to
re-import it every reboot (manual `mount -a` walks fstab sequentially,
so the import itself appeared to work).
All four writers (add-drive, create-pool, import-pool, jellyfin bind
mounts) now remove any existing entry for the target mount point
before appending the fresh line — idempotent and self-healing.
Also add a --version flag, stamped at build time via
-ldflags "-X main.version=...".
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three-tab Bubble Tea TUI (Setup / Manage / Monitor) for setting up and
running a headless Jellyfin server over SSH:
- Setup: install/uninstall Jellyfin, add media drives (single or btrfs
RAID pool), import an existing detached btrfs pool non-destructively,
firewall, move Jellyfin storage onto a media drive
- Boot-drive-safe drive classifier (walks LUKS/LVM/RAID to the physical
disk; never offers a disk hosting /, /boot or swap)
- Keep-existing-filesystem path previews on-disk content, skips starter
folders when content exists, and grants Jellyfin recursive read access
- Manage: copy from external drives, mount/eject, rename/delete
- Monitor: per-core CPU, load/mem/uptime, btrfs error counters, SMART
Single static binary; installs to /usr/local/bin so sudo can find it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>