131 lines
3.4 KiB
Bash
131 lines
3.4 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# scripts/bootstrap/discover-node.sh
|
||
|
|
# Node discovery script for the homelab platform.
|
||
|
|
# Collects system information and outputs it in JSON format.
|
||
|
|
|
||
|
|
set -e
|
||
|
|
|
||
|
|
# Help function
|
||
|
|
show_help() {
|
||
|
|
echo "Usage: $0 [options]"
|
||
|
|
echo "Options:"
|
||
|
|
echo " --json Output in JSON format (default)"
|
||
|
|
echo " --yaml Output in YAML format"
|
||
|
|
echo " --help Show this help"
|
||
|
|
}
|
||
|
|
|
||
|
|
OUTPUT_FORMAT="json"
|
||
|
|
|
||
|
|
while [[ "$#" -gt 0 ]]; do
|
||
|
|
case $1 in
|
||
|
|
--json) OUTPUT_FORMAT="json"; shift ;;
|
||
|
|
--yaml) OUTPUT_FORMAT="yaml"; shift ;;
|
||
|
|
--help) show_help; exit 0 ;;
|
||
|
|
*) echo "Unknown parameter: $1"; show_help; exit 1 ;;
|
||
|
|
esac
|
||
|
|
done
|
||
|
|
|
||
|
|
# Check dependencies
|
||
|
|
for cmd in hostnamectl lscpu free lsblk ip curl; do
|
||
|
|
if ! command -v "$cmd" &> /dev/null; then
|
||
|
|
echo "Error: Required command '$cmd' not found." >&2
|
||
|
|
exit 1
|
||
|
|
fi
|
||
|
|
done
|
||
|
|
|
||
|
|
# Collect Data
|
||
|
|
HOSTNAME=$(hostname)
|
||
|
|
OS_DISTRO=$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)
|
||
|
|
ARCH=$(uname -m)
|
||
|
|
CPU_MODEL=$(lscpu | grep "Model name:" | sed 's/Model name:[[:space:]]*//')
|
||
|
|
CPU_CORES=$(lscpu | grep "^CPU(s):" | awk '{print $2}')
|
||
|
|
CPU_THREADS=$(lscpu | grep "^Thread(s) per core:" | awk '{print $4 * $CPU_CORES}') # Simplistic
|
||
|
|
RAM_TOTAL_GB=$(free -g | grep "Mem:" | awk '{print $2}')
|
||
|
|
|
||
|
|
# Disks
|
||
|
|
DISKS=$(lsblk -dno NAME,SIZE,TYPE,MODEL | grep disk | awk '{printf "{\"name\": \"%s\", \"size\": \"%s\", \"model\": \"%s\"},", $1, $2, $4}' | sed 's/,$//')
|
||
|
|
|
||
|
|
# GPU Presence
|
||
|
|
GPU_PRESENT=false
|
||
|
|
if lspci | grep -i 'vga\|3d\|display' | grep -i 'nvidia\|amd\|intel' > /dev/null; then
|
||
|
|
GPU_PRESENT=true
|
||
|
|
GPU_INFO=$(lspci | grep -i 'vga\|3d\|display' | head -n 1 | cut -d ':' -f3 | sed 's/^[[:space:]]*//')
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Virtualization
|
||
|
|
VIRT_SUPPORTED=false
|
||
|
|
if lscpu | grep "Virtualization:" > /dev/null; then
|
||
|
|
VIRT_SUPPORTED=true
|
||
|
|
VIRT_TYPE=$(lscpu | grep "Virtualization:" | awk '{print $2}')
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Network Interfaces
|
||
|
|
INTERFACES=$(ip -j addr show | jq -c '[.[] | {name: .ifname, active: (if .operstate == "UP" then true else false end), ips: [.addr_info[].local]}]' 2>/dev/null || ip addr show | grep '^[0-9]' | awk '{print $2}' | sed 's/://' | xargs -I {} echo -n "\"{}\", " | sed 's/, $//')
|
||
|
|
|
||
|
|
# Tailscale
|
||
|
|
TAILSCALE_STATUS="not-installed"
|
||
|
|
TAILSCALE_IP="null"
|
||
|
|
if command -v tailscale &> /dev/null; then
|
||
|
|
if tailscale status &> /dev/null; then
|
||
|
|
TAILSCALE_STATUS="active"
|
||
|
|
TAILSCALE_IP=$(tailscale ip -4)
|
||
|
|
else
|
||
|
|
TAILSCALE_STATUS="installed-inactive"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Docker
|
||
|
|
DOCKER_AVAILABLE=false
|
||
|
|
if command -v docker &> /dev/null; then
|
||
|
|
if docker info &> /dev/null; then
|
||
|
|
DOCKER_AVAILABLE=true
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Connectivity
|
||
|
|
CONNECTIVITY="unknown"
|
||
|
|
if curl -s --head https://google.com &> /dev/null; then
|
||
|
|
CONNECTIVITY="internet-access"
|
||
|
|
fi
|
||
|
|
|
||
|
|
# Output Construction (JSON)
|
||
|
|
cat <<EOF
|
||
|
|
{
|
||
|
|
"hostname": "$HOSTNAME",
|
||
|
|
"os": {
|
||
|
|
"distro": "$OS_DISTRO",
|
||
|
|
"arch": "$ARCH"
|
||
|
|
},
|
||
|
|
"hardware": {
|
||
|
|
"cpu": {
|
||
|
|
"model": "$CPU_MODEL",
|
||
|
|
"cores": $CPU_CORES,
|
||
|
|
"threads": $(lscpu | grep "^CPU(s):" | awk '{print $2}')
|
||
|
|
},
|
||
|
|
"memory": {
|
||
|
|
"total_gb": $RAM_TOTAL_GB
|
||
|
|
},
|
||
|
|
"gpu": {
|
||
|
|
"present": $GPU_PRESENT,
|
||
|
|
"info": "${GPU_INFO:-none}"
|
||
|
|
},
|
||
|
|
"disks": [$DISKS]
|
||
|
|
},
|
||
|
|
"virtualization": {
|
||
|
|
"supported": $VIRT_SUPPORTED,
|
||
|
|
"type": "${VIRT_TYPE:-none}"
|
||
|
|
},
|
||
|
|
"network": {
|
||
|
|
"interfaces": $INTERFACES,
|
||
|
|
"tailscale": {
|
||
|
|
"status": "$TAILSCALE_STATUS",
|
||
|
|
"ip": "$TAILSCALE_IP"
|
||
|
|
},
|
||
|
|
"connectivity": "$CONNECTIVITY"
|
||
|
|
},
|
||
|
|
"docker": {
|
||
|
|
"available": $DOCKER_AVAILABLE
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|