forked from finn/tinyboard
200 lines
5.9 KiB
Bash
Executable File
200 lines
5.9 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# hubspoke-helper.sh - Manage hub/spoke rclone mounts over reverse SSH
|
|
#
|
|
# This script helps configure and control the two sides:
|
|
# - Spoke: establishes a reverse SSH tunnel (autossh)
|
|
# - Hub: mounts the spoke's filesystem via rclone/sftp
|
|
#
|
|
# It expects service template files in:
|
|
# ./spoke/autossh-tunnel.service
|
|
# ./hub/rclone-mount@.service
|
|
#
|
|
# Those files can be copied or piped into place by this script.
|
|
|
|
set -euo pipefail
|
|
|
|
# ------------------------------------------------------------
|
|
# Configuration (adjust these to your environment)
|
|
# ------------------------------------------------------------
|
|
SPOKE_AUTOSSH_SERVICE_SRC="./spoke/autossh-tunnel.service"
|
|
HUB_RCLONE_SERVICE_SRC="./hub/rclone-mount@.service"
|
|
|
|
# Default values (can be overridden with environment variables or interactive prompts)
|
|
HUB_USER="${HUB_USER:-armbian}"
|
|
HUB_HOST="${HUB_HOST:-oily.dad}"
|
|
SPOKE_USER="${SPOKE_USER:-armbian}"
|
|
TUNNEL_PORT="${TUNNEL_PORT:-11111}"
|
|
SPOKE_SSH_KEY="${SPOKE_SSH_KEY:-$HOME/.ssh/armbian-brie-202604}"
|
|
RCLONE_REMOTE_NAME="${RCLONE_REMOTE_NAME:-brie-remote}"
|
|
MOUNT_POINT="${MOUNT_POINT:-$HOME/mnt/brie}"
|
|
|
|
# ------------------------------------------------------------
|
|
# Helper functions
|
|
# ------------------------------------------------------------
|
|
usage() {
|
|
cat <<EOF
|
|
Usage: $0 {hub|spoke} {action}
|
|
|
|
Manage hub/spoke rclone setup.
|
|
|
|
ACTIONS FOR SPOKE:
|
|
show-cmd Show the autossh command to run manually
|
|
install Install the autossh system service (requires sudo)
|
|
start Start the installed service (requires sudo)
|
|
stop Stop the installed service (requires sudo)
|
|
status Show status of the autossh service
|
|
|
|
ACTIONS FOR HUB:
|
|
show-cmd Show the manual rclone mount command
|
|
install Install the rclone user service (no sudo)
|
|
start Start the rclone user service
|
|
stop Stop the rclone user service
|
|
status Show status of the rclone user service
|
|
mount Manual foreground mount (for testing)
|
|
unmount Unmount manually (fusermount -u)
|
|
|
|
EXAMPLES:
|
|
$0 spoke show-cmd
|
|
$0 spoke install
|
|
$0 hub install
|
|
$0 hub start
|
|
EOF
|
|
}
|
|
|
|
die() {
|
|
echo "ERROR: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
check_service_file() {
|
|
local file="$1"
|
|
if [ ! -f "$file" ]; then
|
|
die "Service template not found: $file"
|
|
fi
|
|
}
|
|
|
|
# ------------------------------------------------------------
|
|
# Spoke actions
|
|
# ------------------------------------------------------------
|
|
spoke_show_cmd() {
|
|
cat <<EOF
|
|
Run this command manually on the SPOKE to establish the reverse tunnel:
|
|
autossh -M 0 -NT -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" \\
|
|
-R ${TUNNEL_PORT}:localhost:22 -i ${SPOKE_SSH_KEY} ${HUB_USER}@${HUB_HOST}
|
|
EOF
|
|
}
|
|
|
|
spoke_install() {
|
|
check_service_file "$SPOKE_AUTOSSH_SERVICE_SRC"
|
|
echo "Installing autossh system service on SPOKE..."
|
|
sudo cp "$SPOKE_AUTOSSH_SERVICE_SRC" /etc/systemd/system/autossh-tunnel.service
|
|
sudo systemctl daemon-reload
|
|
echo "Service installed. Enable with: sudo systemctl enable autossh-tunnel.service"
|
|
echo "Start with: sudo systemctl start autossh-tunnel.service"
|
|
}
|
|
|
|
spoke_start() {
|
|
sudo systemctl start autossh-tunnel.service
|
|
echo "Started."
|
|
}
|
|
|
|
spoke_stop() {
|
|
sudo systemctl stop autossh-tunnel.service
|
|
echo "Stopped."
|
|
}
|
|
|
|
spoke_status() {
|
|
sudo systemctl status autossh-tunnel.service --no-pager
|
|
}
|
|
|
|
# ------------------------------------------------------------
|
|
# Hub actions
|
|
# ------------------------------------------------------------
|
|
hub_show_cmd() {
|
|
cat <<EOF
|
|
Manual rclone mount command on HUB (run in foreground, Ctrl+C to stop):
|
|
mkdir -p ${MOUNT_POINT}
|
|
rclone mount ${RCLONE_REMOTE_NAME}: ${MOUNT_POINT} \\
|
|
--config ${HOME}/.config/rclone/rclone.conf \\
|
|
--vfs-cache-mode writes \\
|
|
--allow-other
|
|
EOF
|
|
}
|
|
|
|
hub_install() {
|
|
check_service_file "$HUB_RCLONE_SERVICE_SRC"
|
|
echo "Installing rclone user service on HUB..."
|
|
mkdir -p "$HOME/.config/systemd/user"
|
|
cp "$HUB_RCLONE_SERVICE_SRC" "$HOME/.config/systemd/user/rclone-mount@.service"
|
|
systemctl --user daemon-reload
|
|
echo "Service installed. Enable with: systemctl --user enable rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
|
echo "Start with: systemctl --user start rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
|
}
|
|
|
|
hub_start() {
|
|
systemctl --user start "rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
|
echo "Started."
|
|
}
|
|
|
|
hub_stop() {
|
|
systemctl --user stop "rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
|
echo "Stopped."
|
|
}
|
|
|
|
hub_status() {
|
|
systemctl --user status "rclone-mount@${RCLONE_REMOTE_NAME}.service" --no-pager
|
|
}
|
|
|
|
hub_mount() {
|
|
mkdir -p "$MOUNT_POINT"
|
|
echo "Mounting in foreground. Press Ctrl+C to unmount."
|
|
rclone mount "${RCLONE_REMOTE_NAME}:" "$MOUNT_POINT" \
|
|
--config "${HOME}/.config/rclone/rclone.conf" \
|
|
--vfs-cache-mode writes \
|
|
--allow-other
|
|
}
|
|
|
|
hub_unmount() {
|
|
fusermount -u "$MOUNT_POINT" 2>/dev/null && echo "Unmounted." || echo "Not mounted or already unmounted."
|
|
}
|
|
|
|
# ------------------------------------------------------------
|
|
# Main dispatch
|
|
# ------------------------------------------------------------
|
|
if [ $# -lt 2 ]; then
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
ROLE="$1"
|
|
ACTION="$2"
|
|
|
|
case "$ROLE" in
|
|
spoke)
|
|
case "$ACTION" in
|
|
show-cmd) spoke_show_cmd ;;
|
|
install) spoke_install ;;
|
|
start) spoke_start ;;
|
|
stop) spoke_stop ;;
|
|
status) spoke_status ;;
|
|
*) die "Unknown action for spoke: $ACTION" ;;
|
|
esac
|
|
;;
|
|
hub)
|
|
case "$ACTION" in
|
|
show-cmd) hub_show_cmd ;;
|
|
install) hub_install ;;
|
|
start) hub_start ;;
|
|
stop) hub_stop ;;
|
|
status) hub_status ;;
|
|
mount) hub_mount ;;
|
|
unmount) hub_unmount ;;
|
|
*) die "Unknown action for hub: $ACTION" ;;
|
|
esac
|
|
;;
|
|
*)
|
|
usage
|
|
exit 1
|
|
;;
|
|
esac |