forked from finn/tinyboard
remove unused legacy scripts and rclone template
This commit is contained in:
129
hub/offboard-spoke.sh
Normal file
129
hub/offboard-spoke.sh
Normal file
@@ -0,0 +1,129 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
RCLONE_CONF="${HOME}/.config/rclone/rclone.conf"
|
||||
SSH_DIR="${HOME}/.ssh"
|
||||
REGISTRY="${HOME}/.config/tinyboard/spokes"
|
||||
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${GREEN}[+]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[!]${NC} $*"; }
|
||||
die() { echo -e "${RED}[ERROR]${NC} $*" >&2; exit 1; }
|
||||
header() { echo -e "\n${CYAN}══════════════════════════════════════════${NC}"; echo -e "${CYAN} $*${NC}"; echo -e "${CYAN}══════════════════════════════════════════${NC}"; }
|
||||
|
||||
check_deps() {
|
||||
local missing=()
|
||||
for cmd in "$@"; do
|
||||
if ! command -v "$cmd" >/dev/null 2>&1; then
|
||||
missing+=("$cmd")
|
||||
fi
|
||||
done
|
||||
if [ ${#missing[@]} -gt 0 ]; then
|
||||
die "Missing required dependencies: ${missing[*]}"
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "$(id -u)" -eq 0 ]; then
|
||||
die "Run as the hub user, not root."
|
||||
fi
|
||||
|
||||
check_deps rclone crontab fusermount python3
|
||||
|
||||
header "TinyBoard Hub — Offboard Spoke"
|
||||
|
||||
[ -f "$REGISTRY" ] || die "No spoke registry found at $REGISTRY. No spokes to offboard."
|
||||
|
||||
echo "Registered spokes:"
|
||||
echo ""
|
||||
awk '{print " " $1 " (port " $2 ", mount " $4 ")"}' "$REGISTRY"
|
||||
echo ""
|
||||
|
||||
read -rp "Spoke name to offboard: " SPOKE_NAME
|
||||
[ -n "$SPOKE_NAME" ] || die "Spoke name cannot be empty"
|
||||
|
||||
SPOKE_LINE=$(grep "^$SPOKE_NAME " "$REGISTRY" 2>/dev/null || true)
|
||||
[ -n "$SPOKE_LINE" ] || die "Spoke '$SPOKE_NAME' not found in registry."
|
||||
|
||||
TUNNEL_PORT=$(echo "$SPOKE_LINE" | awk '{print $2}')
|
||||
KEY_PATH=$(echo "$SPOKE_LINE" | awk '{print $3}')
|
||||
MOUNT_POINT=$(echo "$SPOKE_LINE" | awk '{print $4}')
|
||||
|
||||
echo ""
|
||||
echo -e " Spoke: ${YELLOW}$SPOKE_NAME${NC}"
|
||||
echo -e " Port: ${YELLOW}$TUNNEL_PORT${NC}"
|
||||
echo -e " Key: ${YELLOW}$KEY_PATH${NC}"
|
||||
echo -e " Mount: ${YELLOW}$MOUNT_POINT${NC}"
|
||||
echo ""
|
||||
read -rp "Are you sure you want to offboard $SPOKE_NAME? [y/N]: " CONFIRM
|
||||
[[ "${CONFIRM,,}" == "y" ]] || die "Aborted."
|
||||
|
||||
header "Unmounting Spoke"
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
if fusermount -u "$MOUNT_POINT" 2>/dev/null; then
|
||||
info "Unmounted $MOUNT_POINT."
|
||||
else
|
||||
warn "Could not unmount $MOUNT_POINT — may already be unmounted."
|
||||
fi
|
||||
else
|
||||
warn "$MOUNT_POINT is not currently mounted."
|
||||
fi
|
||||
|
||||
header "Removing Crontab Entry"
|
||||
EXISTING=$(crontab -l 2>/dev/null || true)
|
||||
UPDATED=$(echo "$EXISTING" | grep -v "${SPOKE_NAME}-remote:" || true)
|
||||
if [ "$EXISTING" = "$UPDATED" ]; then
|
||||
warn "No crontab entry found for $SPOKE_NAME."
|
||||
elif [ -z "$UPDATED" ]; then
|
||||
crontab -r 2>/dev/null || true
|
||||
info "Crontab entry for $SPOKE_NAME removed (crontab now empty)."
|
||||
else
|
||||
echo "$UPDATED" | crontab -
|
||||
info "Crontab entry for $SPOKE_NAME removed."
|
||||
fi
|
||||
|
||||
header "Removing rclone Remote"
|
||||
if grep -q "\[${SPOKE_NAME}-remote\]" "$RCLONE_CONF" 2>/dev/null; then
|
||||
python3 - "$RCLONE_CONF" "$SPOKE_NAME" <<'PYEOF'
|
||||
import sys
|
||||
path, name = sys.argv[1], sys.argv[2]
|
||||
lines = open(path).readlines()
|
||||
out, skip = [], False
|
||||
for line in lines:
|
||||
if line.strip() == f"[{name}-remote]":
|
||||
skip = True
|
||||
elif skip and line.strip().startswith("["):
|
||||
skip = False
|
||||
if not skip:
|
||||
out.append(line)
|
||||
open(path, 'w').writelines(out)
|
||||
PYEOF
|
||||
info "rclone remote [${SPOKE_NAME}-remote] removed from $RCLONE_CONF."
|
||||
else
|
||||
warn "rclone remote [${SPOKE_NAME}-remote] not found in $RCLONE_CONF."
|
||||
fi
|
||||
|
||||
header "Removing SSH Key"
|
||||
read -rp "Remove hub SSH key for $SPOKE_NAME ($KEY_PATH)? [y/N]: " REMOVE_KEY
|
||||
if [[ "${REMOVE_KEY,,}" == "y" ]]; then
|
||||
if [ -f "$KEY_PATH" ]; then
|
||||
rm -f "$KEY_PATH" "$KEY_PATH.pub"
|
||||
info "SSH key removed."
|
||||
else
|
||||
warn "Key not found at $KEY_PATH."
|
||||
fi
|
||||
else
|
||||
info "SSH key left in place."
|
||||
fi
|
||||
|
||||
header "Removing from Registry"
|
||||
(grep -v "^$SPOKE_NAME " "$REGISTRY" || true) > "${REGISTRY}.tmp" && mv "${REGISTRY}.tmp" "$REGISTRY"
|
||||
info "$SPOKE_NAME removed from registry."
|
||||
|
||||
header "Offboarding Complete"
|
||||
echo -e " Spoke ${GREEN}$SPOKE_NAME${NC} has been offboarded."
|
||||
echo ""
|
||||
@@ -1,18 +0,0 @@
|
||||
[brie-remote]
|
||||
type = sftp
|
||||
host = localhost
|
||||
port = 11111
|
||||
key_file = /home/armbian/.ssh/armbian-brie-202604
|
||||
shell_type = unix
|
||||
md5sum_command = md5sum
|
||||
sha1sum_command = sha1sum
|
||||
|
||||
#[new-remote]
|
||||
#type = sftp
|
||||
#host = localhost
|
||||
#port = 11112
|
||||
#key_file = /home/armbian/.ssh/a new priv key for tunnel back to new spoke
|
||||
#shell_type = unix
|
||||
#md5sum_command = md5sum
|
||||
#sha1sum_command = sha1sum
|
||||
|
||||
@@ -1,221 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# hubspoke-helper.sh - Manage hub/spoke rclone mounts
|
||||
# Assumes spoke Docker files exist in ~/autossh-tunnel/
|
||||
# Simplified hub mount uses direct rclone commands (no systemd services)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Configuration (override with env vars if needed)
|
||||
# ------------------------------------------------------------
|
||||
TUNNEL_DIR="${TUNNEL_DIR:-$HOME/tinyboard/spoke}"
|
||||
COMPOSE_FILE="${COMPOSE_FILE:-$TUNNEL_DIR/compose.yaml}"
|
||||
RCLONE_REMOTE="${RCLONE_REMOTE:-brie-remote}"
|
||||
MOUNT_POINT="${MOUNT_POINT:-/mnt/hub/$RCLONE_REMOTE}"
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Usage
|
||||
# ------------------------------------------------------------
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $0 {hub|spoke} {action}
|
||||
|
||||
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 (simplified rclone mount - no systemd):
|
||||
install Show simplified setup instructions
|
||||
start Start rclone mount in background (uses nohup)
|
||||
start-background Start rclone mount in background (for crontab)
|
||||
stop Stop rclone mount
|
||||
status Check mount status
|
||||
mount Manual foreground mount (testing)
|
||||
unmount Unmount manually
|
||||
|
||||
EXAMPLES:
|
||||
$0 spoke build
|
||||
$0 spoke start
|
||||
$0 hub install
|
||||
$0 hub start
|
||||
EOF
|
||||
}
|
||||
|
||||
die() {
|
||||
echo "ERROR: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Spoke actions (docker)
|
||||
# ------------------------------------------------------------
|
||||
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."
|
||||
}
|
||||
|
||||
spoke_start() {
|
||||
cd "$TUNNEL_DIR"
|
||||
docker-compose up -d
|
||||
}
|
||||
|
||||
spoke_stop() {
|
||||
cd "$TUNNEL_DIR"
|
||||
docker-compose down
|
||||
}
|
||||
|
||||
spoke_restart() {
|
||||
cd "$TUNNEL_DIR"
|
||||
docker-compose restart
|
||||
}
|
||||
|
||||
spoke_status() {
|
||||
docker ps --filter name=spoke-autossh --format "table {{.Names}}\t{{.Status}}"
|
||||
}
|
||||
|
||||
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
|
||||
EOF
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Hub actions (simplified - no systemd templates)
|
||||
# ------------------------------------------------------------
|
||||
hub_install() {
|
||||
echo "Simplified hub setup:"
|
||||
echo ""
|
||||
echo "1. Ensure /etc/fuse.conf has 'user_allow_other' uncommented:"
|
||||
echo " sudo sed -i 's/^#user_allow_other/user_allow_other/' /etc/fuse.conf"
|
||||
echo ""
|
||||
echo "2. Ensure you're in the 'fuse' group:"
|
||||
echo " sudo usermod -aG fuse $USER"
|
||||
echo " (You may need to log out and back in for this to take effect)"
|
||||
echo ""
|
||||
echo "3. Create mount point directory:"
|
||||
echo " mkdir -p \"$MOUNT_POINT\""
|
||||
echo ""
|
||||
echo "4. Test manual mount:"
|
||||
echo " $0 hub mount"
|
||||
echo ""
|
||||
echo "5. For auto-start, consider adding to crontab with @reboot:"
|
||||
echo " crontab -e"
|
||||
echo " Add: @reboot $0 hub start-background"
|
||||
echo ""
|
||||
echo "Note: This simplified version doesn't use systemd services."
|
||||
}
|
||||
|
||||
hub_start() {
|
||||
echo "Starting rclone mount in background..."
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
nohup rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
|
||||
--config "${HOME}/.config/rclone/rclone.conf" \
|
||||
--vfs-cache-mode writes \
|
||||
--allow-other \
|
||||
--daemon >/dev/null 2>&1 &
|
||||
echo "Mount started in background (PID: $!)"
|
||||
echo "Check status with: $0 hub status"
|
||||
}
|
||||
|
||||
hub_start_background() {
|
||||
# Internal function for crontab/auto-start
|
||||
mkdir -p "$MOUNT_POINT"
|
||||
rclone mount "${RCLONE_REMOTE}:" "$MOUNT_POINT" \
|
||||
--config "${HOME}/.config/rclone/rclone.conf" \
|
||||
--vfs-cache-mode writes \
|
||||
--allow-other \
|
||||
--daemon
|
||||
}
|
||||
|
||||
hub_stop() {
|
||||
echo "Stopping rclone mount..."
|
||||
if hub_unmount; then
|
||||
echo "Mount stopped."
|
||||
else
|
||||
echo "Could not unmount. Trying force unmount..."
|
||||
fusermount -uz "$MOUNT_POINT" 2>/dev/null && echo "Force unmounted." || echo "Still could not unmount."
|
||||
fi
|
||||
}
|
||||
|
||||
hub_status() {
|
||||
if mountpoint -q "$MOUNT_POINT" 2>/dev/null; then
|
||||
echo "Mount point $MOUNT_POINT is mounted."
|
||||
mount | grep "$MOUNT_POINT"
|
||||
else
|
||||
echo "Mount point $MOUNT_POINT is NOT mounted."
|
||||
echo "Check if rclone process is running:"
|
||||
pgrep -af rclone || echo "No rclone mount processes found."
|
||||
fi
|
||||
}
|
||||
|
||||
hub_mount() {
|
||||
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
|
||||
}
|
||||
|
||||
hub_unmount() {
|
||||
fusermount -u "$MOUNT_POINT" 2>/dev/null && echo "Unmounted." || echo "Not mounted."
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# Dispatch
|
||||
# ------------------------------------------------------------
|
||||
if [ $# -lt 2 ]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROLE="$1"
|
||||
ACTION="$2"
|
||||
|
||||
case "$ROLE" in
|
||||
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 ;;
|
||||
start-background) hub_start_background ;;
|
||||
stop) hub_stop ;;
|
||||
status) hub_status ;;
|
||||
mount) hub_mount ;;
|
||||
unmount) hub_unmount ;;
|
||||
*) die "Unknown action for hub: $ACTION" ;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
@@ -1,8 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Need armbian-config?
|
||||
|
||||
apt install -y vim
|
||||
apt install -y autossh
|
||||
apt install -y docker.io docker-cli docker-compose
|
||||
usermod -aG docker armbian
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copy this along with .not_logged_in_yet to armbian root dir, then run after successful login
|
||||
|
||||
# Refresh: extract MAC address of wlan0
|
||||
MAC=$(netplan status -f json | jq -r '.wlan0.macaddress')
|
||||
|
||||
# Check that we actually got a MAC address
|
||||
if [[ -z "$MAC" ]]; then
|
||||
echo "Error: Could not retrieve MAC address from netplan." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Detected MAC address: $MAC"
|
||||
|
||||
# Assign cheese hostname based on MAC address
|
||||
case "$MAC" in
|
||||
38:9c:80:46:26:c8) # ← Replace with your first real MAC
|
||||
HOSTNAME="brie"
|
||||
;;
|
||||
68:f8:ea:22:e1:3d) # ← Replace with your second real MAC
|
||||
HOSTNAME="gouda"
|
||||
;;
|
||||
99:88:77:66:55:44) # ← Replace with your third real MAC
|
||||
HOSTNAME="camembert"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown MAC address: $MAC ... hostname not changed." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Setting hostname to: $HOSTNAME"
|
||||
sudo hostnamectl set-hostname "$HOSTNAME"
|
||||
|
||||
# Optional: also update /etc/hostname (hostnamectl usually does this, but to be safe)
|
||||
echo "$HOSTNAME" | sudo tee /etc/hostname >/dev/null
|
||||
|
||||
echo "Hostname changed. Reboot or start a new shell to see the change."
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to clean sensitive WiFi credentials and passwords from configuration files
|
||||
# Usage: ./clean_sensitive.sh [filename]
|
||||
|
||||
FILE="${1:-/home/finn/code/tinyboard/armb-not_logged_in_yet}"
|
||||
|
||||
echo "Cleaning sensitive data 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"
|
||||
|
||||
# Clean root password
|
||||
sed -i 's/^\(PRESET_ROOT_PASSWORD=\).*$/\1"[REDACTED]"/' "$FILE"
|
||||
|
||||
# Clean user password
|
||||
sed -i 's/^\(PRESET_USER_PASSWORD=\).*$/\1"[REDACTED]"/' "$FILE"
|
||||
|
||||
echo "wiped fields"
|
||||
Reference in New Issue
Block a user