Files
mac/.claude/handoffs/2026-09-15-222455-tank-automount.md
T
Mortdecai 0377aa3a0b docs: session handoff — tank automount
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-15 22:24:55 -04:00

8.9 KiB

Handoff: tank automount on the Mac (autofs + SMB)

Session Metadata

  • Created: 2026-09-15 22:24:55
  • Project: /home/claude/bin/mac
  • Branch: master
  • Session duration: ~35 min

Recent Commits (for context)

  • c1558d2 feat(tank): autofs SMB mount of tank at /Volumes/tank
  • c204d99 docs: session handoff — ssh aliases + two-key split
  • 2028508 feat(ssh): full homelab alias set on the Mac + separate interactive key
  • 43877eb docs(checklist): kitty needs the Local Network grant — else LAN ssh = No route to host
  • dc29b7a docs: session handoff — kitty titlebar fix

Handoff Chain

Review the previous handoff for full context before filling this one.

Current State Summary

Seth asked to "mount tank on the mac as a drive". Shipped scripts/tank-automount.sh: an autofs direct map (/- auto_smb -nosuid in /etc/auto_master) + root-owned 0600 /etc/auto_smb mounting //Administrator@192.168.0.173/tank (soft) at /Volumes/tank. Mounts on access, unmounts when idle — chosen over a Finder Login-Item mount because the laptop roams. Verified: mount works, writes land as root on tank, two consecutive all-[skip] reruns, wired into run.sh. The literal "as a drive" is NOT achievable this way: macOS marks all automounted fs nobrowse (confirmed in man auto_master), so it shows as a folder and needs a Finder Favorite (added to docs/manual-checklist.md). A Finder window on /Volumes/tank was opened on Seth's screen. Not yet verified across a reboot (FileVault means Seth must be at the lid). Committed + pushed.

Codebase Understanding

Architecture Overview

  • run.sh now has 3 on-Mac stages: setup.sh (temp NOPASSWD sudoers), tank-automount.sh (own sudo -S -v from the stdin password — needs no temp sudoers), then tank-side + authorize-mac-key.sh from steel141.
  • tank export facts (pve173): NFS /tank *(rw,no_root_squash,insecure); Samba shares [tank] and [Z] (same path, force user = root, users Administrator/octoprint). steel141's seth uses //173/Z as Administrator; vdj-rig uses NFS ro with a systemd automount — the roaming pattern this copies.
  • The Mac's seth is uid 501, which is why NFS was rejected: writes would be an unknown uid and only 777 dirs are writable.

Critical Files

File Purpose Relevance
scripts/tank-automount.sh the whole feature; password on stdin idempotent; see header comment for the three macOS gotchas
/etc/auto_smb (on the Mac) contains the SMB password, root 0600 never copy into the repo or .mac-setup-backup
/etc/auto_master (on the Mac) direct-map line appended pre-change copy in ~/.mac-setup-backup/auto_master-<ts> on the Mac
docs/manual-checklist.md new "tank" section + fixed Gitea key + samples step Seth's next GUI actions
DECISIONS.md autofs-vs-Finder-mount rationale; Finder mount in Deferred/Rejected

Key Patterns Discovered

  • macOS automount -vc does NOT create direct-map trigger dirs ("mountpoint unavailable", getattrlist:fail:2). mkdir -p first.
  • No-tty sudo ticket (sudo -S -v over ssh) is per parent pid: sudo in a pipeline or as a direct child works; $(sudo cat ...) silently fails. Cost a false "not idempotent".
  • nobrowse in a map's options and nobrowse on the resulting mount are different things (man page says so); there is no map option that makes an automount Finder-browsable.
  • Secrets to on-Mac scripts go via stdin (printf | ssh mac 'bash script'), never argv/env in the ssh command string; URL-encoding the password also went through python3 stdin, not argv.

Work Completed

Tasks Finished

  • scripts/tank-automount.sh written, applied, verified (mount, root write, idempotent reruns)
  • run.sh runs it after setup.sh
  • docs/manual-checklist.md: tank Favorite + reboot check; Gitea key -> id_ed25519_homelab; samples step now uses /Volumes/tank
  • DECISIONS.md + CLAUDE.md updated; committed + pushed
  • Finder window opened on /Volumes/tank for Seth

Files Modified

File Changes Rationale
[no modified files detected]

Decisions Made

Decision Options Considered Rationale
autofs (roaming-safe, folder) over Finder Login-Item mount (drive icon, hard mount) both; a custom LaunchAgent doing mount_smbfs was the third (rung-7) option laptop leaves the LAN; hard mounts beachball Finder and throw login dialogs. Icon can be revisited
SMB as Administrator over NFS NFS is passwordless uid 501 on the Mac; SMB force user = root matches how seth writes tank from steel141
/Volumes/tank as the path ~/tank, /tank via synthetic.conf reads as a drive path; persistence across reboot is the open question — fallback is synthetic.conf /tank (needs a reboot)
Password in /etc/auto_smb root 0600 keychain (not honoured by automountd) same class as steel141's ~/.smbcredentials; never leaves the Mac

Pending Work

Immediate Next Steps

  1. After Seth's next reboot: ssh mac 'mount | grep auto_smb' must show the /Volumes/tank trigger. If /Volumes/tank vanished (boot-time /Volumes cleanup), switch the map to /tank via /etc/synthetic.conf (tank bare line) — needs another reboot.
  2. Seth: drag /Volumes/tank to Finder Favorites (checklist). Ask whether the folder-not-drive result is acceptable or he wants the Locations icon (then: Finder Connect-to-Server + Login Item, documented as rejected-for-now in DECISIONS).
  3. Carried: authorize-mac-key.sh rerun for bedroom/thinkcentre/seth-pi/pinail/openclaw2; bedroom=root confirmation; kitty relaunch; Ableton install then run.sh --no-tank; audio interface test.

Blockers/Open Questions

  • Reboot persistence of the /Volumes/tank trigger dir — unverified (FileVault: needs Seth at the lid).
  • Idle-unmount timing not measured (macOS default AUTOMOUNT_TIMEOUT in /etc/autofs.conf, 3600 s); fine unless Seth notices.

Deferred Items

  • Real drive icon under Locations (Finder mount + Login Item) — rejected for now, see DECISIONS.
  • LaunchAgent-based mount_smbfs reconnect daemon — would give icon + roaming, but it's custom code for a problem autofs solves well enough.
  • Carried: SparkFun PPP, Tailscale login, AeroSpace, NSWindowShouldDragOnGesture, Gitea key upload.

Context for Resuming Agent

Important Context

/etc/auto_smb on the Mac holds the homelab password — never cat it into a transcript, never back it up into the repo or ~/.mac-setup-backup. If tank "isn't mounting": ls /Volumes/tank is what triggers it (autofs is lazy); check mount | grep tank for the autofs trigger line first — if the trigger is missing, automount -vc failed (usually the dir is gone); if the trigger is there but smbfs isn't, it's network/creds (log show --last 2m --predicate 'process == "automountd"'). Re-running printf '%s\n' "$HOMELAB_PASSWORD" | ssh mac 'bash ~/mac/scripts/tank-automount.sh' is always safe. This session changed on the Mac: /etc/auto_master (+1 line), /etc/auto_smb (new), /Volumes/tank (dir), and opened one Finder window; nothing else.

Assumptions Made

  • Seth's Mac sudo password == $HOMELAB_PASSWORD (true: run.sh's cleanup relies on it) and the Samba Administrator password == the same (verified by the mount succeeding).
  • Seth values roaming-safety over the drive icon (inferred from "portable" use; not confirmed — item 2 in next steps).

Potential Gotchas

  • The Ableton Live 12 Trial Installer DMG was mounted at /Volumes/Ableton Live 12 Trial Installer during this session — Seth is mid-install; don't unmount/eject volumes wholesale.
  • mount | grep tank shows TWO lines (autofs trigger + smbfs) when mounted; only the trigger when idle. Both are normal.
  • sed -i "" (BSD form) is what works on the Mac even with GNU sed on PATH via gnubin — check which sed before scripting sed there.

Environment State

Tools/Services Used

  • ssh mac; /usr/sbin/automount, /usr/libexec/automountd; /usr/bin/python3 (Xcode CLT) used for URL-encoding; gitea push.

Active Processes

  • tank currently mounted at /Volumes/tank on the Mac (will idle-unmount). Finder window open on it. Backup launchd agent unchanged.

Environment Variables

  • HOMELAB_PASSWORD — piped on stdin to tank-automount.sh (and by run.sh); never in argv.
  • Previous handoff: .claude/handoffs/2026-09-15-203133-mac-ssh-aliases.md (two-key ssh design, offline hosts list).
  • man auto_master on the Mac (nobrowse semantics); /etc/autofs.conf (timeouts); ~/bin/CLAUDE.md Storage section (tank export facts, use .173 not .200).

Security Reminder: Before finalizing, run validate_handoff.py to check for accidental secret exposure.