Fix media drive not mounting after reboot (stale fstab entries)

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>
This commit is contained in:
28allday 2026-06-03 22:05:37 +01:00
parent 959e507a83
commit 3786d6bae1
5 changed files with 39 additions and 5 deletions

View file

@ -23,11 +23,22 @@ import (
"tuistream/internal/tui"
)
// version is stamped at build time via:
//
// -ldflags "-X main.version=v0.1.1"
var version = "dev"
func main() {
readOnly := flag.Bool("read-only", false,
"open the TUI without checking for root; only the inventory views work")
showVersion := flag.Bool("version", false, "print the version and exit")
flag.Parse()
if *showVersion {
fmt.Println("tuistream", version)
return
}
if !*readOnly && os.Geteuid() != 0 {
fmt.Fprintln(os.Stderr,
"tuistream needs administrator rights to install Jellyfin, edit /etc/fstab, etc.")

View file

@ -199,7 +199,13 @@ case "$FS" in
esac
LINE="UUID=${UUID} ${MP} ${FS} ${OPTS} 0 2"
grep -qF -- "$LINE" /etc/fstab || printf '%%s\n' "$LINE" >> /etc/fstab
# Drop any stale entries for this mount point first (e.g. the UUID of a drive
# that has since been reformatted). Duplicate mount points make
# systemd-fstab-generator keep only the FIRST line if that one is stale the
# drive never mounts at boot.
awk -v mp="$MP" '$0 ~ /^[[:space:]]*#/ || $2 != mp' /etc/fstab > /etc/fstab.tuistream \
&& cat /etc/fstab.tuistream > /etc/fstab && rm -f /etc/fstab.tuistream
printf '%%s\n' "$LINE" >> /etc/fstab
echo "fstab entry: $LINE"
`,
shellQuote(target),

View file

@ -253,7 +253,13 @@ fi
OPTS="defaults,nofail,x-gvfs-show,x-gvfs-name=$LABEL"
LINE="UUID=${UUID} ${MP} btrfs ${OPTS} 0 0"
grep -qF -- "$LINE" /etc/fstab || printf '%%s\n' "$LINE" >> /etc/fstab
# Drop any stale entries for this mount point first (e.g. the UUID of a pool
# that has since been recreated). Duplicate mount points make
# systemd-fstab-generator keep only the FIRST line if that one is stale the
# pool never mounts at boot and shows up as detached again every reboot.
awk -v mp="$MP" '$0 ~ /^[[:space:]]*#/ || $2 != mp' /etc/fstab > /etc/fstab.tuistream \
&& cat /etc/fstab.tuistream > /etc/fstab && rm -f /etc/fstab.tuistream
printf '%%s\n' "$LINE" >> /etc/fstab
echo "fstab: $LINE"
`,
shellQuote(devs[0]),

View file

@ -169,7 +169,13 @@ fi
OPTS="defaults,nofail,x-gvfs-show,x-gvfs-name=$LABEL"
LINE="UUID=${UUID} ${MP} btrfs ${OPTS} 0 0"
grep -qF -- "$LINE" /etc/fstab || printf '%%s\n' "$LINE" >> /etc/fstab
# Drop any stale entries for this mount point first (e.g. the UUID of a pool
# that has since been recreated). Duplicate mount points make
# systemd-fstab-generator keep only the FIRST line if that one is stale the
# pool never mounts at boot and shows up as detached again every reboot.
awk -v mp="$MP" '$0 ~ /^[[:space:]]*#/ || $2 != mp' /etc/fstab > /etc/fstab.tuistream \
&& cat /etc/fstab.tuistream > /etc/fstab && rm -f /etc/fstab.tuistream
printf '%%s\n' "$LINE" >> /etc/fstab
echo "fstab: $LINE"
`,
shellQuote(dev),

View file

@ -131,8 +131,13 @@ install -d %[2]s %[3]s`,
{
Title: "Add bind mounts to /etc/fstab",
Cmd: bashAsRoot(fmt.Sprintf(`
grep -qsF ' %[2]s ' /etc/fstab || printf '%%s %%s none bind,x-systemd.requires-mounts-for=%[5]s 0 0\n' %[1]s %[2]s >> /etc/fstab
grep -qsF ' %[4]s ' /etc/fstab || printf '%%s %%s none bind,x-systemd.requires-mounts-for=%[5]s 0 0\n' %[3]s %[4]s >> /etc/fstab`,
# Drop any stale bind entries for these targets first (e.g. pointing at a
# previous media drive) duplicate mount points make systemd-fstab-generator
# keep only the FIRST line, so a stale one would win at boot.
awk -v a=%[2]s -v b=%[4]s '$0 ~ /^[[:space:]]*#/ || ($2 != a && $2 != b)' /etc/fstab > /etc/fstab.tuistream \
&& cat /etc/fstab.tuistream > /etc/fstab && rm -f /etc/fstab.tuistream
printf '%%s %%s none bind,x-systemd.requires-mounts-for=%[5]s 0 0\n' %[1]s %[2]s >> /etc/fstab
printf '%%s %%s none bind,x-systemd.requires-mounts-for=%[5]s 0 0\n' %[3]s %[4]s >> /etc/fstab`,
shellQuote(data), defaultDataDir,
shellQuote(cache), defaultCacheDir,
mp)),