|
#!/bin/bash |
|
|
|
# auto_mount_winboat.sh |
|
# keeps the the SSH shared Winboat file system mounted |
|
|
|
# ~/.local/bin/auto_mount_winboat.sh |
|
|
|
# Configuration |
|
REMOTE_USER="jim" # Use *your* username |
|
CONTAINER_NAME="WinBoat" |
|
MOUNT_POINT="$HOME/winboat_home" # Use $HOME instead of ~ for your home directory |
|
PORT="2222" |
|
HOST="127.0.0.1" |
|
|
|
# Logging Configuration |
|
# Options: DEBUG, INFO, WARN, ERROR |
|
LOG_LEVEL="ERROR" |
|
# DEBUG = All messages |
|
# ERROR = Minimum messages |
|
|
|
# Poll Timers |
|
HEALTHY_POLL=5 # Seconds to sleep when mounted/healthy |
|
CONNECTION_POLL=1 # Seconds to sleep when waiting for connection/startup |
|
RESTART_POLL=10 # Seconds between container restarts |
|
|
|
# Flag file: If this exists, we will NOT auto-start the container. |
|
MANUAL_MODE_FILE="$HOME/.winboat_manual_mode" |
|
|
|
# --------------------------------------------------------- |
|
# Logging Engine |
|
# --------------------------------------------------------- |
|
declare -A LOG_LEVELS=([DEBUG]=0 [INFO]=1 [WARN]=2 [ERROR]=3) |
|
|
|
log() { |
|
local priority="$1" |
|
local message="$2" |
|
|
|
# 1. Check if priority exists |
|
if [[ -z "${LOG_LEVELS[$priority]}" ]]; then |
|
echo "ERROR: Invalid log level $priority" |
|
return 1 |
|
fi |
|
|
|
# 2. Compare against current configured level |
|
local current_val="${LOG_LEVELS[$LOG_LEVEL]}" |
|
local msg_val="${LOG_LEVELS[$priority]}" |
|
|
|
if (( msg_val >= current_val )); then |
|
# Print with timestamp |
|
echo "[$(date '+%H:%M:%S')] [$priority] $message" |
|
fi |
|
} |
|
|
|
# --------------------------------------------------------- |
|
# Main Logic |
|
# --------------------------------------------------------- |
|
|
|
# Ensure directory exists |
|
mkdir -p "$MOUNT_POINT" |
|
|
|
# Function to check if container is running |
|
is_container_running() { |
|
# Returns 0 if running, 1 if not |
|
[ "$(podman container inspect -f '{{.State.Running}}' $CONTAINER_NAME 2>/dev/null)" == "true" ] |
|
} |
|
|
|
log "INFO" "Starting WinBoat Monitor (Level: $LOG_LEVEL)..." |
|
|
|
while true; do |
|
# ----------------------------- |
|
# STATE 1: CHECK EXISTING MOUNT |
|
# ----------------------------- |
|
if mountpoint -q "$MOUNT_POINT"; then |
|
# The folder is mounted. Check if it's responsive. |
|
# We use 'stat' with a 3-second timeout. |
|
timeout 3s stat "$MOUNT_POINT" >/dev/null 2>&1 |
|
|
|
if [ $? -eq 0 ]; then |
|
# HEALTHY: Mount is good. Sleep longer to save resources. |
|
# Only log this in DEBUG mode to avoid spamming logs |
|
log "DEBUG" "Mount is healthy." |
|
sleep $HEALTHY_POLL |
|
continue |
|
else |
|
# STALE: The mount is dead (timeout or error). |
|
log "WARN" "⚠️ Mount is stale/unresponsive. Forcing unmount..." |
|
fusermount -uz "$MOUNT_POINT" |
|
if [ $? -eq 0 ]; then |
|
log "INFO" "✅ Successfully unmounted stale path." |
|
else |
|
log "WARN" "❌ Failed to unmount. Will retry next loop." |
|
fi |
|
continue |
|
fi |
|
fi |
|
|
|
# -------------------------------------- |
|
# STATE 2: CHECK CONTAINER & AUTO-START |
|
# -------------------------------------- |
|
# If we are here, we are NOT mounted. |
|
|
|
# Is the SSH port open? |
|
if nc -z -w 1 $HOST $PORT >/dev/null 2>&1; then |
|
log "DEBUG" "🔌 Port $PORT is open. Attempting mount..." |
|
|
|
UID_GID="-o uid=$(id -u) -o gid=$(id -g)" |
|
|
|
# Mount Options: |
|
# reconnect: Try to reconnect if TCP drops |
|
# ServerAliveInterval=15: Keep connection alive |
|
# StrictHostKeyChecking=no: Don't panic if the container IP/ID changes slightly |
|
sshfs -p $PORT $UID_GID -o reconnect,ServerAliveInterval=15,StrictHostKeyChecking=no "$REMOTE_USER@$HOST:" "$MOUNT_POINT" |
|
|
|
if [ $? -eq 0 ]; then |
|
log "INFO" "✅ Success: Mounted at $MOUNT_POINT" |
|
continue |
|
else |
|
log "WARN" "❌ Error: Mount failed. Retrying in ${CONNECTION_POLL}s..." |
|
sleep $CONNECTION_POLL |
|
continue |
|
fi |
|
fi |
|
|
|
# ----------------------------- |
|
# STATE 3: OFFLINE HANDLING |
|
# ----------------------------- |
|
# Port is closed. Is the container even running? |
|
if is_container_running; then |
|
# Container is UP, but Port is CLOSED. It is likely booting or rebooting. |
|
log "INFO" "⏳ Container running, waiting for SSH..." |
|
sleep $CONNECTION_POLL |
|
else |
|
# Container is DOWN. |
|
if [ -f "$MANUAL_MODE_FILE" ]; then |
|
# Manual mode is ON. Do nothing. |
|
log "DEBUG" "💤 Container is down (Manual Mode Active)." |
|
sleep $HEALTHY_POLL |
|
else |
|
# Manual mode is OFF. Auto-start! |
|
log "INFO" "🚀 Container is down. Auto-starting $CONTAINER_NAME..." |
|
podman start "$CONTAINER_NAME" |
|
|
|
# Give it a moment to avoid rapid-fire restart loops if it fails instantly |
|
sleep $RESTART_POLL |
|
fi |
|
fi |
|
done |