1
0
forked from finn/tinyboard
Files
tinyboard/hubspoke-helper.sh

173 lines
4.3 KiB
Bash
Raw Normal View History

2026-04-13 12:31:45 -07:00
#!/usr/bin/env bash
#
2026-04-13 12:53:14 -07:00
# hubspoke-helper.sh - Manage hub/spoke rclone mounts
# Assumes spoke Docker files exist in ~/autossh-tunnel/
# Assumes hub rclone service template is manually placed (or not needed)
2026-04-13 12:31:45 -07:00
set -euo pipefail
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
# Configuration (override with env vars if needed)
2026-04-13 12:31:45 -07:00
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
TUNNEL_DIR="${TUNNEL_DIR:-$HOME/tinyboard/spoke}"
COMPOSE_FILE="${COMPOSE_FILE:-$TUNNEL_DIR/compose.yaml}"
RCLONE_REMOTE="${RCLONE_REMOTE:-brie-remote}"
2026-04-13 12:31:45 -07:00
MOUNT_POINT="${MOUNT_POINT:-$HOME/mnt/brie}"
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
# Usage
2026-04-13 12:31:45 -07:00
# ------------------------------------------------------------
usage() {
2026-04-13 12:53:14 -07:00
cat <<EOF
2026-04-13 12:31:45 -07:00
Usage: $0 {hub|spoke} {action}
2026-04-13 12:53:14 -07:00
SPOKE ACTIONS (docker-based, no systemd):
build Build the autossh image (run once)
start Start the tunnel container
stop Stop the tunnel container
restart Restart the tunnel container
status Show container status
logs Show container logs
show-cmd Show manual autossh command (non-docker)
HUB ACTIONS (systemd user service for rclone mount):
install Install the rclone user service (needs service file)
start Start the rclone mount service
stop Stop the rclone mount service
status Show service status
mount Manual foreground mount (testing)
unmount Unmount manually
2026-04-13 12:31:45 -07:00
EXAMPLES:
2026-04-13 12:53:14 -07:00
$0 spoke build
$0 spoke start
2026-04-13 12:31:45 -07:00
$0 hub install
$0 hub start
EOF
}
die() {
2026-04-13 12:53:14 -07:00
echo "ERROR: $*" >&2
exit 1
2026-04-13 12:31:45 -07:00
}
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
# Spoke actions (docker)
2026-04-13 12:31:45 -07:00
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
spoke_build() {
if [ ! -f "$COMPOSE_FILE" ]; then
die "docker-compose.yaml not found at $COMPOSE_FILE"
fi
cd "$TUNNEL_DIR"
docker build --build-arg UID=$(id -u armbian) --build-arg GID=$(id -g armbian) -t spoke-autossh .
echo "Image built. Use '$0 spoke start' to run."
2026-04-13 12:31:45 -07:00
}
spoke_start() {
2026-04-13 12:53:14 -07:00
cd "$TUNNEL_DIR"
docker-compose up -d
2026-04-13 12:31:45 -07:00
}
spoke_stop() {
2026-04-13 12:53:14 -07:00
cd "$TUNNEL_DIR"
docker-compose down
}
spoke_restart() {
cd "$TUNNEL_DIR"
docker-compose restart
2026-04-13 12:31:45 -07:00
}
spoke_status() {
2026-04-13 12:53:14 -07:00
docker ps --filter name=spoke-autossh --format "table {{.Names}}\t{{.Status}}"
2026-04-13 12:31:45 -07:00
}
2026-04-13 12:53:14 -07:00
spoke_logs() {
cd "$TUNNEL_DIR"
docker-compose logs --tail=50 -f
}
spoke_show_cmd() {
cat <<EOF
Manual autossh command (run on spoke):
autossh -M 0 -NT -o "ServerAliveInterval=60" -o "ServerAliveCountMax=3" \\
-R 11111:localhost:22 -i ~/.ssh/oilykey2026 armbian@oily.dad
2026-04-13 12:31:45 -07:00
EOF
}
2026-04-13 12:53:14 -07:00
# ------------------------------------------------------------
# Hub actions (rclone user service)
# ------------------------------------------------------------
2026-04-13 12:31:45 -07:00
hub_install() {
2026-04-13 12:53:14 -07:00
echo "Assuming you have placed rclone-mount@.service in ~/.config/systemd/user/"
echo "Also, 'sudo loginctl enable-linger armbian' and a reboot may be necessary."
2026-04-13 12:53:14 -07:00
echo "If not, create it manually. Then run: systemctl --user daemon-reload"
systemctl --user daemon-reload
2026-04-13 12:31:45 -07:00
}
hub_start() {
2026-04-13 12:53:14 -07:00
systemctl --user start "rclone-mount@${RCLONE_REMOTE}.service"
2026-04-13 12:31:45 -07:00
}
hub_stop() {
2026-04-13 12:53:14 -07:00
systemctl --user stop "rclone-mount@${RCLONE_REMOTE}.service"
2026-04-13 12:31:45 -07:00
}
hub_status() {
2026-04-13 12:53:14 -07:00
systemctl --user status "rclone-mount@${RCLONE_REMOTE}.service" --no-pager
2026-04-13 12:31:45 -07:00
}
hub_mount() {
2026-04-13 12:53:14 -07:00
mkdir -p "$MOUNT_POINT"
echo "Mounting in foreground. Press Ctrl+C to unmount."
rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
--config "${HOME}/.config/rclone/rclone.conf" \
--vfs-cache-mode writes \
--allow-other
2026-04-13 12:31:45 -07:00
}
hub_unmount() {
2026-04-13 12:53:14 -07:00
fusermount -u "$MOUNT_POINT" 2>/dev/null && echo "Unmounted." || echo "Not mounted."
2026-04-13 12:31:45 -07:00
}
# ------------------------------------------------------------
2026-04-13 12:53:14 -07:00
# Dispatch
2026-04-13 12:31:45 -07:00
# ------------------------------------------------------------
if [ $# -lt 2 ]; then
2026-04-13 12:53:14 -07:00
usage
exit 1
2026-04-13 12:31:45 -07:00
fi
ROLE="$1"
ACTION="$2"
case "$ROLE" in
2026-04-13 12:53:14 -07:00
spoke)
case "$ACTION" in
build) spoke_build ;;
start) spoke_start ;;
stop) spoke_stop ;;
restart) spoke_restart ;;
status) spoke_status ;;
logs) spoke_logs ;;
show-cmd) spoke_show_cmd ;;
*) die "Unknown action for spoke: $ACTION" ;;
esac
;;
hub)
case "$ACTION" in
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