From 154882b0dd756b3dfcacf39b4bb2e7e90c6ba392 Mon Sep 17 00:00:00 2001 From: Hannes Date: Sun, 1 Nov 2026 19:43:41 +0100 Subject: [PATCH] feat: add sshfs auto-mount script for Tailscale/Remote NAS with performance optimizations --- scripts/mount_sshfs.sh | 157 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100755 scripts/mount_sshfs.sh diff --git a/scripts/mount_sshfs.sh b/scripts/mount_sshfs.sh new file mode 100755 index 0000000..364500d --- /dev/null +++ b/scripts/mount_sshfs.sh @@ -0,0 +1,157 @@ +#!/usr/bin/env bash + +# ============================================================ +# TrueNAS SSHFS Auto-Mount (Tailscale / Remote) +# Arch Linux +# ============================================================ + +set -u + +# ---- Configuration ----------------------------------------- + +NAS_HOST="NAS" +MOUNT_BASE="/home/honney/mount" + +mount_points=( + "$MOUNT_BASE/Data" + "$MOUNT_BASE/Media" + "$MOUNT_BASE/Ripping" + "$MOUNT_BASE/Apps" +) + +remote_paths=( + "/mnt/tank/Data" + "/mnt/tank/Media" + "/mnt/tank/Ripping" + "/mnt/tank/Apps" +) + +# SSHFS performance and reliability options (~30ms latency optimized) +SSHFS_OPTIONS="reconnect,ServerAliveInterval=15,ServerAliveCountMax=3,ConnectTimeout=8,ConnectionAttempts=1,cache=yes,attr_timeout=30,entry_timeout=30,negative_timeout=5" + +# SSH connection test options +SSH_OPTIONS=( + -o BatchMode=yes + -o ConnectTimeout=8 + -o ConnectionAttempts=1 +) + +# ---- Logging ----------------------------------------------- + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" +} + +# ---- Dependencies ------------------------------------------ + +for cmd in sshfs ssh mountpoint findmnt tailscale; do + if ! command -v "$cmd" >/dev/null 2>&1; then + log "ERROR: Required command missing: $cmd" + exit 1 + fi +done + +# ---- Tailscale connectivity -------------------------------- + +log "Checking Tailscale..." + +if ! tailscale status >/dev/null 2>&1; then + log "ERROR: Tailscale is not running or connected." + exit 1 +fi + +# Verify that the NAS is reachable through SSH using your ~/.ssh/config alias +if ! ssh "${SSH_OPTIONS[@]}" "$NAS_HOST" true; then + log "ERROR: Cannot establish SSH connection to $NAS_HOST." + log "Check Tailscale connectivity and your ~/.ssh/config entry." + exit 1 +fi + +log "NAS reachable via SSH." +echo + +# ---- Mount functions --------------------------------------- + +is_mounted() { + mountpoint -q "$1" +} + +mount_sshfs() { + local remote_path="$1" + local mount_point="$2" + + # Create mount directory if missing + if [[ ! -d "$mount_point" ]]; then + log "Creating mount point: $mount_point" + + if ! mkdir -p "$mount_point"; then + log "ERROR: Cannot create $mount_point" + return 1 + fi + fi + + log "Mounting $remote_path -> $mount_point" + + if sshfs \ + "$NAS_HOST:$remote_path" \ + "$mount_point" \ + -o "$SSHFS_OPTIONS"; then + + log "SUCCESS: $mount_point mounted." + return 0 + else + log "ERROR: Failed to mount $mount_point" + return 1 + fi +} + +# ---- Main -------------------------------------------------- + +success=0 +failed=0 +skipped=0 + +for i in "${!mount_points[@]}"; do + + mount_point="${mount_points[$i]}" + remote_path="${remote_paths[$i]}" + + log "Checking: $mount_point" + + if is_mounted "$mount_point"; then + + fstype=$(findmnt -rn -M "$mount_point" -o FSTYPE) + + if [[ "$fstype" == "fuse.sshfs" ]]; then + log "Already mounted: $mount_point" + ((skipped+=1)) + else + log "WARNING: Mount point occupied by another filesystem: $fstype" + ((failed+=1)) + fi + + else + + if mount_sshfs "$remote_path" "$mount_point"; then + ((success+=1)) + else + ((failed+=1)) + fi + + fi + + echo + +done + +# ---- Summary ----------------------------------------------- + +log "================================================" +log "SSHFS mounting finished." +log "Successfully mounted: $success" +log "Already mounted: $skipped" +log "Failed: $failed" +log "================================================" + +# Return failure if any mount failed +(( failed == 0 )) \ No newline at end of file