feat: add sshfs auto-mount script for Tailscale/Remote NAS with performance optimizations
This commit is contained in:
1 parent
ededc51718
commit
154882b0dd
1 file changed
+157
Executable
+157
@@ -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 ))
|
||||||
Reference in new issue
Block a user