forked from finn/tinyboard
restructure
This commit is contained in:
@@ -1,16 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Simple script to clean WiFi SSID and KEY from configuration files
|
|
||||||
# Usage: ./clean_wifi.sh [filename]
|
|
||||||
|
|
||||||
FILE="${1:-/home/finn/code/tinyboard/armb-not_logged_in_yet}"
|
|
||||||
|
|
||||||
echo "Cleaning WiFi credentials from: $FILE"
|
|
||||||
|
|
||||||
# Clean WiFi SSID (both commented and uncommented lines)
|
|
||||||
sed -i 's/^\(#*PRESET_NET_WIFI_SSID=\).*$/\1"[REDACTED]"/' "$FILE"
|
|
||||||
|
|
||||||
# Clean WiFi KEY (both commented and uncommented lines)
|
|
||||||
sed -i 's/^\(#*PRESET_NET_WIFI_KEY=\).*$/\1"[REDACTED]"/' "$FILE"
|
|
||||||
|
|
||||||
echo "creds wiped"
|
|
||||||
@@ -1,200 +1,172 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
#
|
#
|
||||||
# hubspoke-helper.sh - Manage hub/spoke rclone mounts over reverse SSH
|
# hubspoke-helper.sh - Manage hub/spoke rclone mounts
|
||||||
#
|
# Assumes spoke Docker files exist in ~/autossh-tunnel/
|
||||||
# This script helps configure and control the two sides:
|
# Assumes hub rclone service template is manually placed (or not needed)
|
||||||
# - 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
|
set -euo pipefail
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Configuration (adjust these to your environment)
|
# Configuration (override with env vars if needed)
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
SPOKE_AUTOSSH_SERVICE_SRC="./spoke/autossh-tunnel.service"
|
TUNNEL_DIR="${TUNNEL_DIR:-$HOME/tinyboard/spoke}"
|
||||||
HUB_RCLONE_SERVICE_SRC="./hub/rclone-mount@.service"
|
COMPOSE_FILE="${COMPOSE_FILE:-$TUNNEL_DIR/compose.yaml}"
|
||||||
|
RCLONE_REMOTE="${RCLONE_REMOTE:-brie-remote}"
|
||||||
# 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}"
|
MOUNT_POINT="${MOUNT_POINT:-$HOME/mnt/brie}"
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Helper functions
|
# Usage
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
usage() {
|
usage() {
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
Usage: $0 {hub|spoke} {action}
|
Usage: $0 {hub|spoke} {action}
|
||||||
|
|
||||||
Manage hub/spoke rclone setup.
|
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)
|
||||||
|
|
||||||
ACTIONS FOR SPOKE:
|
HUB ACTIONS (systemd user service for rclone mount):
|
||||||
show-cmd Show the autossh command to run manually
|
install Install the rclone user service (needs service file)
|
||||||
install Install the autossh system service (requires sudo)
|
start Start the rclone mount service
|
||||||
start Start the installed service (requires sudo)
|
stop Stop the rclone mount service
|
||||||
stop Stop the installed service (requires sudo)
|
status Show service status
|
||||||
status Show status of the autossh service
|
mount Manual foreground mount (testing)
|
||||||
|
unmount Unmount manually
|
||||||
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:
|
EXAMPLES:
|
||||||
$0 spoke show-cmd
|
$0 spoke build
|
||||||
$0 spoke install
|
$0 spoke start
|
||||||
$0 hub install
|
$0 hub install
|
||||||
$0 hub start
|
$0 hub start
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
die() {
|
die() {
|
||||||
echo "ERROR: $*" >&2
|
echo "ERROR: $*" >&2
|
||||||
exit 1
|
exit 1
|
||||||
}
|
|
||||||
|
|
||||||
check_service_file() {
|
|
||||||
local file="$1"
|
|
||||||
if [ ! -f "$file" ]; then
|
|
||||||
die "Service template not found: $file"
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Spoke actions
|
# Spoke actions (docker)
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
spoke_show_cmd() {
|
spoke_build() {
|
||||||
cat <<EOF
|
if [ ! -f "$COMPOSE_FILE" ]; then
|
||||||
Run this command manually on the SPOKE to establish the reverse tunnel:
|
die "docker-compose.yaml not found at $COMPOSE_FILE"
|
||||||
autossh -M 0 -NT -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" \\
|
fi
|
||||||
-R ${TUNNEL_PORT}:localhost:22 -i ${SPOKE_SSH_KEY} ${HUB_USER}@${HUB_HOST}
|
cd "$TUNNEL_DIR"
|
||||||
EOF
|
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."
|
||||||
|
|
||||||
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() {
|
spoke_start() {
|
||||||
sudo systemctl start autossh-tunnel.service
|
cd "$TUNNEL_DIR"
|
||||||
echo "Started."
|
docker-compose up -d
|
||||||
}
|
}
|
||||||
|
|
||||||
spoke_stop() {
|
spoke_stop() {
|
||||||
sudo systemctl stop autossh-tunnel.service
|
cd "$TUNNEL_DIR"
|
||||||
echo "Stopped."
|
docker-compose down
|
||||||
|
}
|
||||||
|
|
||||||
|
spoke_restart() {
|
||||||
|
cd "$TUNNEL_DIR"
|
||||||
|
docker-compose restart
|
||||||
}
|
}
|
||||||
|
|
||||||
spoke_status() {
|
spoke_status() {
|
||||||
sudo systemctl status autossh-tunnel.service --no-pager
|
docker ps --filter name=spoke-autossh --format "table {{.Names}}\t{{.Status}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
spoke_logs() {
|
||||||
# Hub actions
|
cd "$TUNNEL_DIR"
|
||||||
# ------------------------------------------------------------
|
docker-compose logs --tail=50 -f
|
||||||
hub_show_cmd() {
|
}
|
||||||
cat <<EOF
|
|
||||||
Manual rclone mount command on HUB (run in foreground, Ctrl+C to stop):
|
spoke_show_cmd() {
|
||||||
mkdir -p ${MOUNT_POINT}
|
cat <<EOF
|
||||||
rclone mount ${RCLONE_REMOTE_NAME}: ${MOUNT_POINT} \\
|
Manual autossh command (run on spoke):
|
||||||
--config ${HOME}/.config/rclone/rclone.conf \\
|
autossh -M 0 -NT -o "ServerAliveInterval=60" -o "ServerAliveCountMax=3" \\
|
||||||
--vfs-cache-mode writes \\
|
-R 11111:localhost:22 -i ~/.ssh/oilykey2026 armbian@oily.dad
|
||||||
--allow-other
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# Hub actions (rclone user service)
|
||||||
|
# ------------------------------------------------------------
|
||||||
hub_install() {
|
hub_install() {
|
||||||
check_service_file "$HUB_RCLONE_SERVICE_SRC"
|
echo "Assuming you have placed rclone-mount@.service in ~/.config/systemd/user/"
|
||||||
echo "Installing rclone user service on HUB..."
|
echo "If not, create it manually. Then run: systemctl --user daemon-reload"
|
||||||
mkdir -p "$HOME/.config/systemd/user"
|
systemctl --user daemon-reload
|
||||||
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() {
|
hub_start() {
|
||||||
systemctl --user start "rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
systemctl --user start "rclone-mount@${RCLONE_REMOTE}.service"
|
||||||
echo "Started."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hub_stop() {
|
hub_stop() {
|
||||||
systemctl --user stop "rclone-mount@${RCLONE_REMOTE_NAME}.service"
|
systemctl --user stop "rclone-mount@${RCLONE_REMOTE}.service"
|
||||||
echo "Stopped."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hub_status() {
|
hub_status() {
|
||||||
systemctl --user status "rclone-mount@${RCLONE_REMOTE_NAME}.service" --no-pager
|
systemctl --user status "rclone-mount@${RCLONE_REMOTE}.service" --no-pager
|
||||||
}
|
}
|
||||||
|
|
||||||
hub_mount() {
|
hub_mount() {
|
||||||
mkdir -p "$MOUNT_POINT"
|
mkdir -p "$MOUNT_POINT"
|
||||||
echo "Mounting in foreground. Press Ctrl+C to unmount."
|
echo "Mounting in foreground. Press Ctrl+C to unmount."
|
||||||
rclone mount "${RCLONE_REMOTE_NAME}:" "$MOUNT_POINT" \
|
rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
|
||||||
--config "${HOME}/.config/rclone/rclone.conf" \
|
--config "${HOME}/.config/rclone/rclone.conf" \
|
||||||
--vfs-cache-mode writes \
|
--vfs-cache-mode writes \
|
||||||
--allow-other
|
--allow-other
|
||||||
}
|
}
|
||||||
|
|
||||||
hub_unmount() {
|
hub_unmount() {
|
||||||
fusermount -u "$MOUNT_POINT" 2>/dev/null && echo "Unmounted." || echo "Not mounted or already unmounted."
|
fusermount -u "$MOUNT_POINT" 2>/dev/null && echo "Unmounted." || echo "Not mounted."
|
||||||
}
|
}
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Main dispatch
|
# Dispatch
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
if [ $# -lt 2 ]; then
|
if [ $# -lt 2 ]; then
|
||||||
usage
|
usage
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
ROLE="$1"
|
ROLE="$1"
|
||||||
ACTION="$2"
|
ACTION="$2"
|
||||||
|
|
||||||
case "$ROLE" in
|
case "$ROLE" in
|
||||||
spoke)
|
spoke)
|
||||||
case "$ACTION" in
|
case "$ACTION" in
|
||||||
show-cmd) spoke_show_cmd ;;
|
build) spoke_build ;;
|
||||||
install) spoke_install ;;
|
start) spoke_start ;;
|
||||||
start) spoke_start ;;
|
stop) spoke_stop ;;
|
||||||
stop) spoke_stop ;;
|
restart) spoke_restart ;;
|
||||||
status) spoke_status ;;
|
status) spoke_status ;;
|
||||||
*) die "Unknown action for spoke: $ACTION" ;;
|
logs) spoke_logs ;;
|
||||||
esac
|
show-cmd) spoke_show_cmd ;;
|
||||||
;;
|
*) die "Unknown action for spoke: $ACTION" ;;
|
||||||
hub)
|
esac
|
||||||
case "$ACTION" in
|
;;
|
||||||
show-cmd) hub_show_cmd ;;
|
hub)
|
||||||
install) hub_install ;;
|
case "$ACTION" in
|
||||||
start) hub_start ;;
|
install) hub_install ;;
|
||||||
stop) hub_stop ;;
|
start) hub_start ;;
|
||||||
status) hub_status ;;
|
stop) hub_stop ;;
|
||||||
mount) hub_mount ;;
|
status) hub_status ;;
|
||||||
unmount) hub_unmount ;;
|
mount) hub_mount ;;
|
||||||
*) die "Unknown action for hub: $ACTION" ;;
|
unmount) hub_unmount ;;
|
||||||
esac
|
*) die "Unknown action for hub: $ACTION" ;;
|
||||||
;;
|
esac
|
||||||
*)
|
;;
|
||||||
usage
|
*)
|
||||||
exit 1
|
usage
|
||||||
;;
|
exit 1
|
||||||
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
|||||||
8
spoke/Dockerfile
Normal file
8
spoke/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM debian:bookworm-slim
|
||||||
|
RUN apt-get update && apt-get install -y autossh openssh-client && rm -rf /var/lib/apt/lists/*
|
||||||
|
ARG UID=1000
|
||||||
|
ARG GID=1000
|
||||||
|
RUN groupadd -g ${GID} armbian && useradd -m -u ${UID} -g armbian armbian
|
||||||
|
USER armbian
|
||||||
|
WORKDIR /home/armbian
|
||||||
|
CMD ["autossh", "-M", "0", "-N"]
|
||||||
20
spoke/compose.yaml
Normal file
20
spoke/compose.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
version: '3.8'
|
||||||
|
services:
|
||||||
|
autossh:
|
||||||
|
image: spoke-autossh
|
||||||
|
container_name: spoke-autossh
|
||||||
|
restart: always
|
||||||
|
network_mode: host
|
||||||
|
environment:
|
||||||
|
- AUTOSSH_GATETIME=0
|
||||||
|
command: >
|
||||||
|
autossh -M 0 -NT
|
||||||
|
-o "ServerAliveInterval=60"
|
||||||
|
-o "ServerAliveCountMax=3"
|
||||||
|
-R 11111:localhost:22
|
||||||
|
-i /home/armbian/.ssh/oilykey2026
|
||||||
|
armbian@oily.dad
|
||||||
|
volumes:
|
||||||
|
- /home/armbian/.ssh/oilykey2026:/home/armbian/.ssh/oilykey2026:ro
|
||||||
|
- /home/armbian/.ssh/known_hosts:/home/armbian/.ssh/known_hosts:ro
|
||||||
|
- /home/armbian/share:/home/armbian/share
|
||||||
Reference in New Issue
Block a user