1
0
forked from finn/tinyboard

restructure

This commit is contained in:
2026-04-13 12:53:14 -07:00
parent 05a5928a56
commit 299f6c5355
8 changed files with 132 additions and 148 deletions

View File

@@ -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"

View File

@@ -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
View 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
View 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