Skip to content

Instantly share code, notes, and snippets.

@jimmckeeth
Last active December 24, 2025 06:01
Show Gist options
  • Select an option

  • Save jimmckeeth/118be1ef178c66e9d566ebb123582ea6 to your computer and use it in GitHub Desktop.

Select an option

Save jimmckeeth/118be1ef178c66e9d566ebb123582ea6 to your computer and use it in GitHub Desktop.
Winboat Auto Mount Service

Winboat Automount

This is an updated script that monitors the port 2222 and the ~/winboat_home share (configurable), restarting the winboat container if it goes offline, and remounting the sahre when it is available.

This assumes podman and needs some additional generalization.

Installation, Configuration, & Usage

Update the watcher script with your Windows username and save it in the following location

~/.local/bin/auto_mount_winboat.sh

Make the watcher executable

# make it executable
chmod +x ~/.local/bin/auto_mount_winboat.sh
# create user services directory
mkdir -p ~/.config/systemd/user/ 
# create our service file
nano ~/.config/systemd/user/winboat-mounter.service 

Make sure the .service file points to your service watcher.

Active the service:

# Reload systemd to see the new file
systemctl --user daemon-reload

# Enable it to start on login
systemctl --user enable winboat-mounter.service

# Start it right now
systemctl --user start winboat-mounter.service

It should display something like

Created symlink /home/jim/.config/systemd/user/default.target.wants/winboat-mounter.service → /home/jim/.config/systemd/user/winboat-mounter.service.

If you take your container offline intentionally then use

touch ~/.winboat_manual_mode

And the watcher service won't autostart while that file exists. Remove it when you what the watcher to autostart the container again.

rm ~/.winboat_manual_mode

auto_mount_winboat.sh has configurable logging levels to aid in debugging.

#!/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
# winboat-mounter.service
# ~/.config/systemd/user/default.target.wants/winboat-mounter.service
# launches the watcher script
# Make sure it points to your watcher script location, using %h instead of ~ for your home folder.
[Unit]
Description=Auto-mount WinBoat SSHFS
After=network.target
[Service]
ExecStart=%h/.local/bin/auto_mount_winboat.sh
Restart=always
RestartSec=10
# Crucial: Only kill the watcher script, not the container it started
KillMode=process
[Install]
WantedBy=default.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment