#!/usr/bin/env bash # scripts/onboard/steps/00-preflight.sh — READ-ONLY remote node discovery # # Collects facts from the remote node and prints: # 1. A human-readable report block # 2. A machine-readable YAML snippet ready to paste into hosts//node.yaml # # NO mutations are performed on the remote host. # Depends on: lib/common.sh (sourced by orchestrator), lib/remote.sh (sourced here) set -euo pipefail STEP_NAME="00-preflight" # remote.sh is sourced here so individual steps can also be run standalone # (when REPO_ROOT is in the environment). : "${REPO_ROOT:?REPO_ROOT is not set — run via onboard.sh}" # shellcheck source=../lib/remote.sh source "${REPO_ROOT}/scripts/onboard/lib/remote.sh" step "[$STEP_NAME] Collecting facts from ${ONBOARD_SSH_USER}@${ONBOARD_SSH_HOST} (read-only)" # ── gather all facts in a single SSH session ────────────────────────────────── raw=$(rrun bash -s <<'REMOTE' set -euo pipefail # arch / bitness arch=$(uname -m) bits=$(getconf LONG_BIT) # RAM (kB → MB) mem_kb=$(grep MemTotal /proc/meminfo | awk '{print $2}') mem_mb=$(( mem_kb / 1024 )) # disk root disk_root=$(df -h / | awk 'NR==2{print $2" total, "$3" used, "$4" free ("$5" used)"}') # docker docker_present=false docker_info="" if command -v docker >/dev/null 2>&1; then docker_present=true docker_info=$(docker info --format '{{.ServerVersion}}' 2>/dev/null || echo "unknown") fi # tailscale tailscale_present=false tailscale_status="" if command -v tailscale >/dev/null 2>&1; then tailscale_present=true tailscale_status=$(tailscale status --json 2>/dev/null | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('BackendState','unknown'))" 2>/dev/null || tailscale status 2>/dev/null | head -1 || echo "unknown") fi # Magic Mirror runtime detection mm_runtime="none" if systemctl is-active --quiet MagicMirror 2>/dev/null || systemctl is-active --quiet magicmirror 2>/dev/null; then mm_runtime="systemd" elif command -v pm2 >/dev/null 2>&1 && pm2 list 2>/dev/null | grep -qi "MagicMirror"; then mm_runtime="pm2" elif pgrep -fa "MagicMirror" >/dev/null 2>&1; then mm_runtime="process" fi # swap swap_current="none" if command -v swapon >/dev/null 2>&1; then swap_lines=$(swapon --show --noheadings 2>/dev/null || true) if [[ -n "$swap_lines" ]]; then swap_current="$swap_lines" fi fi if command -v zramctl >/dev/null 2>&1; then zram_lines=$(zramctl --noheadings 2>/dev/null || true) [[ -n "$zram_lines" ]] && swap_current="${swap_current:+$swap_current; }zram: $zram_lines" fi # hostname / os hostname=$(hostname -f 2>/dev/null || hostname) os_pretty=$(grep PRETTY_NAME /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d '"' || echo "unknown") cat <