#!/usr/bin/env bash set -euo pipefail 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}"; } [ "$(id -u)" -eq 0 ] || die "Run as root" header "TinyBoard Network Setup" info "Available interfaces:" ip -o link show | awk -F': ' 'NR>1 {print " " $2}' echo "" read -rp "Enter interface name to configure (e.g. wlan0, eth0, end0): " IFACE [ -n "$IFACE" ] || die "Interface name cannot be empty" ip link show "$IFACE" >/dev/null 2>&1 || die "Interface $IFACE not found" IS_WIFI=false if [[ "$IFACE" == wl* ]]; then IS_WIFI=true info "Wireless interface detected." else info "Wired interface detected — skipping WiFi credential setup." fi CURRENT_IP=$(ip -o -4 addr show "$IFACE" 2>/dev/null | awk '{print $4}' | head -1) CURRENT_GW=$(ip route show default 2>/dev/null | awk '/default/ {print $3}' | head -1) echo "" info "Current IP: ${CURRENT_IP:-none}" info "Current gateway: ${CURRENT_GW:-none}" echo "" read -rp "Set a static IP for this spoke? [Y/n]: " SET_STATIC SET_STATIC="${SET_STATIC:-y}" if [[ "${SET_STATIC,,}" != "y" ]]; then info "Keeping DHCP. No changes made." exit 0 fi header "Static IP Configuration" read -rp "Enter static IP with prefix (e.g. 192.168.1.69/24): " STATIC_IP [ -n "$STATIC_IP" ] || die "IP address cannot be empty" DEFAULT_GW="${CURRENT_GW:-192.168.1.1}" read -rp "Gateway [${DEFAULT_GW}]: " GATEWAY GATEWAY="${GATEWAY:-$DEFAULT_GW}" read -rp "DNS servers (comma-separated) [${GATEWAY},8.8.8.8]: " DNS_INPUT DNS_INPUT="${DNS_INPUT:-${GATEWAY},8.8.8.8}" DNS_YAML="" IFS=',' read -ra DNS_LIST <<< "$DNS_INPUT" for DNS in "${DNS_LIST[@]}"; do DNS=$(echo "$DNS" | tr -d ' ') DNS_YAML="${DNS_YAML} - ${DNS}\n" done info "Current netplan configs:" ls /etc/netplan/ | sed 's/^/ /' echo "" NETPLAN_FILE=$(ls /etc/netplan/*.yaml 2>/dev/null | head -1) read -rp "Netplan file to update [${NETPLAN_FILE}]: " INPUT_FILE NETPLAN_FILE="${INPUT_FILE:-$INPUT_FILE}" NETPLAN_FILE="${NETPLAN_FILE:-$(ls /etc/netplan/*.yaml 2>/dev/null | head -1)}" [ -n "$NETPLAN_FILE" ] || die "No netplan file specified" if $IS_WIFI; then header "WiFi Credentials" CURRENT_SSID="" if [ -f "$NETPLAN_FILE" ]; then CURRENT_SSID=$(grep -A1 'access-points:' "$NETPLAN_FILE" 2>/dev/null | tail -1 | tr -d ' "' | sed 's/:$//' || true) fi KEEP_WIFI="n" if [ -n "$CURRENT_SSID" ]; then warn "Existing WiFi config found for: $CURRENT_SSID" read -rp "Keep existing WiFi credentials? [Y/n]: " KEEP_WIFI KEEP_WIFI="${KEEP_WIFI:-y}" fi if [[ "${KEEP_WIFI,,}" != "y" ]]; then read -rp "WiFi SSID: " WIFI_SSID [ -n "$WIFI_SSID" ] || die "SSID cannot be empty" read -rsp "WiFi password: " WIFI_PASS echo "" [ -n "$WIFI_PASS" ] || die "Password cannot be empty" else WIFI_SSID="$CURRENT_SSID" WIFI_PASS=$(grep -A2 "\"${WIFI_SSID}\"" "$NETPLAN_FILE" 2>/dev/null | grep password | awk -F': ' '{print $2}' | tr -d '"' || true) fi fi header "Writing Netplan Config" if [ -f "$NETPLAN_FILE" ]; then cp "$NETPLAN_FILE" "${NETPLAN_FILE}.bak" info "Backup saved to ${NETPLAN_FILE}.bak" fi if $IS_WIFI; then cat > "$NETPLAN_FILE" < "$NETPLAN_FILE" </dev/null; then info "Netplan config applied successfully." else warn "netplan try timed out or failed — applying anyway..." netplan apply fi STATIC_ADDR="${STATIC_IP%%/*}" echo "" echo -e "${YELLOW}══════════════════════════════════════════${NC}" echo -e "${YELLOW} Network reconfigured.${NC}" echo -e "${YELLOW} If you are connected via SSH, your session${NC}" echo -e "${YELLOW} may drop. Reconnect to: ${STATIC_ADDR}${NC}" echo -e "${YELLOW} Then run: sudo ./setup-spoke.sh${NC}" echo -e "${YELLOW}══════════════════════════════════════════${NC}" echo ""