133 lines
5.3 KiB
Bash
Executable File
133 lines
5.3 KiB
Bash
Executable File
#!/bin/bash
|
||
|
||
###############################################################################
|
||
# Load Configuration from json
|
||
###############################################################################
|
||
|
||
# Require the config‑file path as the first argument:
|
||
CONFIG_FILE="$1"
|
||
|
||
if [[ -z "$CONFIG_FILE" ]]; then
|
||
echo "[ERROR] No path to config file given"
|
||
exit 1
|
||
fi
|
||
|
||
# Ensure the file actually exists:
|
||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||
echo "[ERROR] Config file '$CONFIG_FILE' not found."
|
||
exit 1
|
||
fi
|
||
|
||
# Ensure jq is installed before proceeding.
|
||
if ! command -v jq >/dev/null 2>&1; then
|
||
echo "[ERROR] 'jq' is not installed. Please install jq and try again."
|
||
exit 1
|
||
fi
|
||
|
||
# extract the server names at the top level:
|
||
SERVERS=($(jq -r 'keys[]' "$CONFIG_FILE"))
|
||
|
||
###############################################################################
|
||
# Function Definitions
|
||
###############################################################################
|
||
# Check if the SSH tunnel on a given local port is active
|
||
is_tunnel_active() {
|
||
local port=$1
|
||
timeout 1 bash -c "</dev/tcp/localhost/${port}" &>/dev/null
|
||
}
|
||
|
||
# Check if the given mount point is currently mounted
|
||
is_nfs_mounted() {
|
||
local mount_point=$1
|
||
mount | grep -q "${mount_point}"
|
||
}
|
||
|
||
# Check if the mount point directory is accessible (i.e. can be listed)
|
||
is_mount_accessible() {
|
||
local mount_point=$1
|
||
ls -1 "${mount_point}" >/dev/null 2>&1
|
||
}
|
||
|
||
###############################################################################
|
||
# Main Loop: Process Each Server and Its Mount Points
|
||
###############################################################################
|
||
for server in "${SERVERS[@]}"; do
|
||
SSH_USER=$(jq -r ".[\"${server}\"].SSH_USER" "$CONFIG_FILE")
|
||
SSH_SERVER=$(jq -r ".[\"${server}\"].SSH_SERVER" "$CONFIG_FILE")
|
||
SSH_SERVER_PORT=$(jq -r ".[\"${server}\"].SSH_SERVER_PORT" "$CONFIG_FILE")
|
||
REMOTE_NFS_PORT=$(jq -r ".[\"${server}\"].REMOTE_NFS_PORT" "$CONFIG_FILE")
|
||
LOCAL_PORT_BASE=$(jq -r ".[\"${server}\"].LOCAL_PORT_BASE" "$CONFIG_FILE")
|
||
|
||
readarray -t MOUNT_POINTS < <(jq -r ".[\"${server}\"].MOUNT_POINTS[]" "$CONFIG_FILE")
|
||
readarray -t NFS_SHARES < <(jq -r ".[\"${server}\"].NFS_SHARES[]" "$CONFIG_FILE")
|
||
|
||
echo "-------------------------------------------------"
|
||
echo "[INFO] Processing server: ${SSH_SERVER}"
|
||
|
||
# Loop over each mount configuration for the current server.
|
||
for i in "${!MOUNT_POINTS[@]}"; do
|
||
MOUNT_POINT="${MOUNT_POINTS[$i]}"
|
||
NFS_SHARE="${NFS_SHARES[$i]}"
|
||
# Calculate a unique local port: base + index offset
|
||
LOCAL_PORT=$(( LOCAL_PORT_BASE + i ))
|
||
|
||
echo "-------------------------------------------------"
|
||
echo "[INFO] Setting up mount for ${MOUNT_POINT}"
|
||
echo "[INFO] NFS Share: ${NFS_SHARE}"
|
||
echo "[INFO] Using local port: ${LOCAL_PORT}"
|
||
|
||
# Check and (re)establish the SSH tunnel if needed.
|
||
if ! is_tunnel_active "${LOCAL_PORT}"; then
|
||
echo "[INFO] SSH Tunnel on port ${LOCAL_PORT} is down. Attempting to reconnect..."
|
||
ssh -f -N -L "${LOCAL_PORT}:localhost:${REMOTE_NFS_PORT}" \
|
||
-o ExitOnForwardFailure=yes \
|
||
-p "${SSH_SERVER_PORT}" \
|
||
"${SSH_USER}@${SSH_SERVER}"
|
||
|
||
if is_tunnel_active "${LOCAL_PORT}"; then
|
||
echo "[SUCCESS] SSH Tunnel established on local port ${LOCAL_PORT}."
|
||
else
|
||
echo "[ERROR] Failed to establish SSH tunnel for mount ${MOUNT_POINT}!"
|
||
continue # Skip mounting for this configuration if tunnel fails
|
||
fi
|
||
else
|
||
echo "[INFO] SSH Tunnel already active on port ${LOCAL_PORT}."
|
||
fi
|
||
|
||
# Ensure the mount point directory exists
|
||
if [ ! -d "${MOUNT_POINT}" ]; then
|
||
echo "[INFO] Creating mount point directory: ${MOUNT_POINT}"
|
||
sudo mkdir -p "${MOUNT_POINT}"
|
||
fi
|
||
|
||
# Check if the NFS share is mounted and accessible.
|
||
if is_nfs_mounted "${MOUNT_POINT}"; then
|
||
if ! is_mount_accessible "${MOUNT_POINT}"; then
|
||
echo "[WARNING] Mount point ${MOUNT_POINT} is not accessible. Attempting to remount..."
|
||
sudo umount "${MOUNT_POINT}"
|
||
sleep 2
|
||
sudo mount -t nfs -o ro,port="${LOCAL_PORT}",nolock,soft,timeo=5,retrans=3 127.0.0.1:"${NFS_SHARE}" "${MOUNT_POINT}"
|
||
if is_mount_accessible "${MOUNT_POINT}"; then
|
||
echo "[SUCCESS] Remounted successfully and folder is now accessible."
|
||
else
|
||
echo "[ERROR] Remount failed, folder still not accessible."
|
||
fi
|
||
else
|
||
echo "[INFO] NFS share is mounted and accessible at ${MOUNT_POINT}."
|
||
fi
|
||
else
|
||
echo "[INFO] NFS share is not mounted at ${MOUNT_POINT}. Attempting to mount..."
|
||
sudo mount -t nfs -o ro,port="${LOCAL_PORT}",nolock,soft,timeo=5,retrans=3 127.0.0.1:"${NFS_SHARE}" "${MOUNT_POINT}"
|
||
if is_mount_accessible "${MOUNT_POINT}"; then
|
||
echo "[SUCCESS] NFS share mounted successfully at ${MOUNT_POINT}."
|
||
else
|
||
echo "[ERROR] Failed to mount NFS share ${NFS_SHARE} at ${MOUNT_POINT} or folder not accessible!"
|
||
fi
|
||
fi
|
||
|
||
done
|
||
done
|
||
|
||
echo "-------------------------------------------------"
|
||
echo "[INFO] All server mount configurations processed."
|