From 7070f6548cd14260fea09d2da20a394e1ab88cf6 Mon Sep 17 00:00:00 2001 From: Cobra Date: Tue, 7 Apr 2026 13:20:15 -0400 Subject: [PATCH] Add reimage bootstrap: deploy.sh, setup_wifi.sh, fix setup.sh enable/reinstall, idempotent DB inserts --- scripts/build_data.py | 8 ++--- scripts/deploy.sh | 84 +++++++++++++++++++++++++++++++++++++++++++ scripts/setup_wifi.sh | 62 ++++++++++++++++++++++++++++++++ setup.sh | 48 ++++++++++++++++++------- 4 files changed, 186 insertions(+), 16 deletions(-) create mode 100644 scripts/deploy.sh create mode 100644 scripts/setup_wifi.sh diff --git a/scripts/build_data.py b/scripts/build_data.py index faea8ea..589f6d2 100755 --- a/scripts/build_data.py +++ b/scripts/build_data.py @@ -177,9 +177,9 @@ def create_innocuous_macs_db(db_path: str) -> None: ] conn.executemany(""" - INSERT INTO mac_profiles (device_type, oui, vendor, device_name, - dhcp_hostname, dhcp_vendor_class, - ttl, tcp_window, os_family) + INSERT OR IGNORE INTO mac_profiles (device_type, oui, vendor, device_name, + dhcp_hostname, dhcp_vendor_class, + ttl, tcp_window, os_family) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) """, profiles) @@ -317,7 +317,7 @@ def create_os_sigs_db(db_path: str) -> None: ] conn.executemany(""" - INSERT INTO signatures (ttl, window, df, mss, os, version) + INSERT OR IGNORE INTO signatures (ttl, window, df, mss, os, version) VALUES (?, ?, ?, ?, ?, ?) """, sigs) diff --git a/scripts/deploy.sh b/scripts/deploy.sh new file mode 100644 index 0000000..8f4d5ac --- /dev/null +++ b/scripts/deploy.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env bash +# BigBrother remote deploy — push source to a fresh device and run setup. +# Usage: bash scripts/deploy.sh [user@host] [--enable-service] [--no-tools] [--reinstall] +set -euo pipefail + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m' +info() { echo -e "${GREEN}[+]${NC} $*"; } +warn() { echo -e "${YELLOW}[!]${NC} $*"; } +error() { echo -e "${RED}[-]${NC} $*"; exit 1; } +step() { echo -e "${CYAN}[*]${NC} ${BOLD}$*${NC}"; } + +TARGET="root@10.0.0.0" +SETUP_FLAGS="" +SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)" + +while [[ $# -gt 0 ]]; do + case "$1" in + --enable-service) SETUP_FLAGS="$SETUP_FLAGS --enable-service"; shift ;; + --no-tools) SETUP_FLAGS="$SETUP_FLAGS --no-tools"; shift ;; + --reinstall) SETUP_FLAGS="$SETUP_FLAGS --reinstall"; shift ;; + -h|--help) + echo "Usage: $0 [user@host] [--enable-service] [--no-tools] [--reinstall]" + echo " user@host Target device (default: root@10.0.0.0)" + echo " --enable-service Enable and start bigbrother-core after setup" + echo " --no-tools Skip GitHub tool downloads" + echo " --reinstall Force reinstall all components" + exit 0 + ;; + *@*) TARGET="$1"; shift ;; + *) error "Unknown option: $1" ;; + esac +done + +HOST="${TARGET#*@}" + +step "BigBrother remote deploy → ${TARGET}" +echo " Source: ${SCRIPT_DIR}" +echo " Flags: ${SETUP_FLAGS:-none}" +echo "" + +# ── 1. Verify SSH connectivity ─────────────────────────────────────────────── +step "Checking SSH connectivity..." +DEADLINE=$(( $(date +%s) + 30 )) +while ! ssh -o StrictHostKeyChecking=no -o ConnectTimeout=3 -o BatchMode=yes "$TARGET" true 2>/dev/null; do + if [[ $(date +%s) -ge $DEADLINE ]]; then + error "Cannot reach ${TARGET} after 30s. Is the device up and SSH running?" + fi + warn " Waiting for SSH on ${HOST}..." + sleep 3 +done +info "SSH OK" + +# ── 2. Sync source to device ───────────────────────────────────────────────── +step "Syncing source to ${HOST}:/tmp/bb-deploy/ ..." +rsync -az --delete \ + --exclude='.git' \ + --exclude='.venv' \ + --exclude='storage/' \ + --exclude='__pycache__' \ + --exclude='*.pyc' \ + --exclude='*.db' \ + -e "ssh -o StrictHostKeyChecking=no" \ + "${SCRIPT_DIR}/" "${TARGET}:/tmp/bb-deploy/" +info "Source synced" + +# ── 3. Run setup ───────────────────────────────────────────────────────────── +step "Running setup.sh on ${HOST}..." +# shellcheck disable=SC2029 +ssh -o StrictHostKeyChecking=no -t "$TARGET" "cd /tmp/bb-deploy && bash setup.sh $SETUP_FLAGS" +SETUP_EXIT=$? + +if [[ $SETUP_EXIT -ne 0 ]]; then + warn "setup.sh exited with code ${SETUP_EXIT}" + warn "Check logs: ssh ${TARGET} 'tail -50 /tmp/bb_setup_*.log'" + exit $SETUP_EXIT +fi + +# ── 4. Final status ────────────────────────────────────────────────────────── +echo "" +step "Deployment status" +ssh -o StrictHostKeyChecking=no "$TARGET" \ + "systemctl is-active bigbrother-core.service 2>/dev/null && echo 'Service: running' || echo 'Service: not running (use --enable-service to start)'" + +info "Deploy complete. Connect: ssh ${TARGET}" diff --git a/scripts/setup_wifi.sh b/scripts/setup_wifi.sh new file mode 100644 index 0000000..d51e92c --- /dev/null +++ b/scripts/setup_wifi.sh @@ -0,0 +1,62 @@ +#!/usr/bin/env bash +# Write a NetworkManager WiFi profile to an unmounted Armbian SD card. +# Run this on the machine where the SD card is mounted BEFORE first boot. +# +# Usage: bash scripts/setup_wifi.sh SSID PASSPHRASE [MOUNT_POINT] +# MOUNT_POINT defaults to /media/$USER/armbi_root +set -euo pipefail + +RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; NC='\033[0m' +info() { echo -e "${GREEN}[+]${NC} $*"; } +warn() { echo -e "${YELLOW}[!]${NC} $*"; } +error() { echo -e "${RED}[-]${NC} $*"; exit 1; } + +SSID="${1:-}" +PASSPHRASE="${2:-}" +MOUNT="${3:-/media/${USER:-root}/armbi_root}" + +[[ -z "$SSID" || -z "$PASSPHRASE" ]] && { + echo "Usage: $0 SSID PASSPHRASE [MOUNT_POINT]" + echo " MOUNT_POINT defaults to /media/\$USER/armbi_root" + exit 1 +} + +[[ -d "$MOUNT" ]] || error "Mount point not found: $MOUNT — is the SD card mounted?" + +NM_DIR="${MOUNT}/etc/NetworkManager/system-connections" +NM_FILE="${NM_DIR}/wifi-bb.nmconnection" + +mkdir -p "$NM_DIR" + +cat > "$NM_FILE" << EOF +[connection] +id=wifi-bb +type=wifi +autoconnect=true + +[wifi] +mode=infrastructure +ssid=${SSID} + +[wifi-security] +auth-alg=open +key-mgmt=wpa-psk +psk=${PASSPHRASE} + +[ipv4] +method=auto + +[ipv6] +method=disabled +EOF + +chmod 600 "$NM_FILE" +info "WiFi profile written to ${NM_FILE}" +info "SSID: ${SSID}" +echo "" +info "After first boot, device should connect automatically." +warn "If it doesn't connect, SSH in via Ethernet or serial and run:" +warn " nmcli dev wifi connect '${SSID}' password ''" +echo "" +info "Once connected, deploy BigBrother with:" +info " bash scripts/deploy.sh root@ --enable-service" diff --git a/setup.sh b/setup.sh index d3a6081..fead5d4 100755 --- a/setup.sh +++ b/setup.sh @@ -24,6 +24,7 @@ FLAG_REINSTALL=0 FLAG_JUMPBOX=0 FLAG_NO_TOOLS=0 FLAG_VERIFY_ONLY=0 +FLAG_ENABLE_SVC=0 # ── Output helpers ────────────────────────────────────────────────────────── info() { echo -e "${GREEN}[+]${NC} $*"; } @@ -47,22 +48,24 @@ usage() { echo "Usage: $0 [OPTIONS]" echo "" echo "Options:" - echo " --reinstall Force reinstall all components" - echo " --jumpbox Minimal install for RPi Zero 2W jumpbox mode" - echo " --no-tools Skip GitHub tool installation" - echo " --verify-only Check installation without changes" - echo " -h, --help Show this help" + echo " --reinstall Force reinstall all components" + echo " --jumpbox Minimal install for RPi Zero 2W jumpbox mode" + echo " --no-tools Skip GitHub tool installation" + echo " --enable-service Enable and start bigbrother-core.service after setup" + echo " --verify-only Check installation without changes" + echo " -h, --help Show this help" exit 0 } while [[ $# -gt 0 ]]; do case "$1" in - --reinstall) FLAG_REINSTALL=1; shift ;; - --jumpbox) FLAG_JUMPBOX=1; shift ;; - --no-tools) FLAG_NO_TOOLS=1; shift ;; - --verify-only) FLAG_VERIFY_ONLY=1; shift ;; - -h|--help) usage ;; - *) die "Unknown option: $1" ;; + --reinstall) FLAG_REINSTALL=1; shift ;; + --jumpbox) FLAG_JUMPBOX=1; shift ;; + --no-tools) FLAG_NO_TOOLS=1; shift ;; + --enable-service) FLAG_ENABLE_SVC=1; shift ;; + --verify-only) FLAG_VERIFY_ONLY=1; shift ;; + -h|--help) usage ;; + *) die "Unknown option: $1" ;; esac done @@ -691,7 +694,9 @@ if [[ ! -f "$BUILD_DATA" ]]; then fi if [[ -f "$BUILD_DATA" ]]; then - "${VENV_DIR}/bin/python3" "$BUILD_DATA" --output-dir "${INSTALL_DIR}/data" >> "$LOG_FILE" 2>&1 + BUILD_DATA_FLAGS="--output-dir ${INSTALL_DIR}/data" + [[ $FLAG_REINSTALL -eq 1 ]] && BUILD_DATA_FLAGS="$BUILD_DATA_FLAGS --force" + "${VENV_DIR}/bin/python3" "$BUILD_DATA" $BUILD_DATA_FLAGS >> "$LOG_FILE" 2>&1 info "Data databases created" else warn "build_data.py not found -- databases will need to be created manually" @@ -847,3 +852,22 @@ echo " Mode: $(if [[ $FLAG_JUMPBOX -eq 1 ]]; then echo 'jumpbox (minimal echo " Log: ${LOG_FILE}" echo "" info "Run '${INSTALL_DIR}/bigbrother.py' to start" + +# ════════════════════════════════════════════════════════════════════════════ +# 12. ENABLE AND START SERVICE +# ════════════════════════════════════════════════════════════════════════════ +if [[ $FLAG_ENABLE_SVC -eq 1 ]]; then + step "Enabling and starting bigbrother-core service..." + if systemctl enable bigbrother-core.service 2>/dev/null; then + info "bigbrother-core.service enabled" + else + warn "Failed to enable bigbrother-core.service" + fi + if systemctl start bigbrother-core.service 2>/dev/null; then + info "bigbrother-core.service started" + sleep 3 + systemctl status bigbrother-core.service --no-pager -l 2>/dev/null || true + else + warn "Failed to start bigbrother-core.service — check journalctl -u bigbrother-core" + fi +fi