PROP OUT: keep Location Assets mounted on the ProP Mac; SHARE NOT MOUNTED; hold remounts

- remote-access/mac-keep-mounted.sh: a user LaunchAgent that keeps a share mounted (every minute and at
  login; Keychain login; unmount + remount only when the share hangs), installed on NA ProP for
  Chronicles' Location Assets
- PROP OUT says SHARE NOT MOUNTED instead of NOT IN <weekend> when the share is gone; its hold (and
  auto-fix) starts the agent and waits for the share

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 11:22:07 -04:00
co-authored by Claude Opus 5.5
parent 11ac8aa8e0
commit e2add3b27e
8 changed files with 110 additions and 6 deletions
+55
View File
@@ -0,0 +1,55 @@
#!/bin/zsh
# Keeps a network share mounted on this Mac (2026-10-22: Location Assets dropped off NA ProP and PROP OUT
# could not see the bundle). Installs a LaunchAgent for the logged-in user that looks every minute and at
# login: mounted and answering = nothing; not mounted = mount it again with the login saved in the Keychain
# (tick "Remember this password" when connecting once by hand); mounted but dead (after sleep or a network
# drop) = unmount it, then mount it again. Never asks for a password and never shows a dialog.
#
# Run on the Mac, as the user who uses the share:
# zsh mac-keep-mounted.sh <name> <smb URL> <mount point>
# zsh mac-keep-mounted.sh location-assets "smb://Kenobi@Chronicles-NA._smb._tcp.local/Location%20Assets" "/Volumes/Location Assets"
# Undo: launchctl bootout gui/$(id -u)/org.waterschurch.keep-mounted.<name>; rm ~/Library/LaunchAgents/org.waterschurch.keep-mounted.<name>.plist ~/Library/Scripts/keep-mounted-<name>.sh
set -e
NAME=$1 URL=$2 MP=$3
[[ -n $NAME && -n $URL && -n $MP ]] || { echo "usage: zsh mac-keep-mounted.sh <name> <smb URL> <mount point>" >&2; exit 2; }
LABEL=org.waterschurch.keep-mounted.$NAME
SCRIPT=$HOME/Library/Scripts/keep-mounted-$NAME.sh
LOG=$HOME/Library/Logs/keep-mounted-$NAME.log
HOST=${${URL#*://}#*@}; HOST=${HOST%%/*}
mkdir -p "$HOME/Library/Scripts" "$HOME/Library/LaunchAgents" "$HOME/Library/Logs"
cat > "$SCRIPT" <<EOS
#!/bin/zsh
# Keep $MP mounted ($URL). Installed by the status panel's mac-keep-mounted.sh; see that file to undo.
MP="$MP"; URL="$URL"; HOST="$HOST"; LOG="$LOG"
say() { print -r -- "\$(date '+%Y-%m-%d %H:%M:%S') \$*" >> "\$LOG"; }
if mount | grep -qF " on \$MP ("; then
# Dead only when looking at it hangs (killed after 20 s: status 142). A refusal (macOS's privacy rules for
# a background job) or any other error leaves a working share alone.
/usr/bin/perl -e 'alarm 20; exec @ARGV' /bin/df "\$MP" >/dev/null 2>&1
[[ \$? -ne 142 ]] && exit 0
say "mounted but not answering (20 s): unmounting"
/usr/sbin/diskutil unmount force "\$MP" >> "\$LOG" 2>&1 || /sbin/umount -f "\$MP" >> "\$LOG" 2>&1 || true
fi
SERVER=\${HOST%%._smb._tcp.local}; SERVER=\${SERVER%%.local}
if ! /usr/bin/perl -e 'alarm 6; exec @ARGV' /usr/bin/nc -z -G 4 "\$SERVER.local" 445 >/dev/null 2>&1; then
exit 0 # the server is not on the network right now: try again in a minute
fi
say "not mounted: mounting \$URL"
/usr/bin/osascript -e 'with timeout of 40 seconds' -e "mount volume \"\$URL\"" -e 'end timeout' >> "\$LOG" 2>&1 || say "mount failed"
mount | grep -qF " on \$MP (" && say "mounted at \$MP" || say "not at \$MP after mounting: \$(mount | grep -i smbfs | tr '\n' ' ')"
EOS
chmod 755 "$SCRIPT"
cat > "$HOME/Library/LaunchAgents/$LABEL.plist" <<EOP
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
<key>Label</key><string>$LABEL</string>
<key>ProgramArguments</key><array><string>/bin/zsh</string><string>$SCRIPT</string></array>
<key>RunAtLoad</key><true/>
<key>StartInterval</key><integer>60</integer>
<key>ProcessType</key><string>Background</string>
</dict></plist>
EOP
launchctl bootout "gui/$(id -u)/$LABEL" 2>/dev/null || true
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/$LABEL.plist"
echo "installed $LABEL: keeps $MP mounted (log: $LOG)"