#!/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 ))