# Bootstrap a new node for the Scobleclaw k3s cluster # # Usage: ./bootstrap-node.sh # # Prerequisites: # - NixOS installed on target node # - SSH access to root@ # - This repo cloned locally # set -euo pipefail HOSTNAME="${1:?Usage: bootstrap-node.sh }" TSIP="${2:?Need tailscale IP}" ROLE="${3:-agent}" REPO_DIR="$(cd "$(dirname "$0")/.." && pwd)" echo "==> Bootstrapping $HOSTNAME ($TSIP) as k3s $ROLE" # 1. Generate cluster token if it doesn't exist TOKEN_FILE="/var/lib/k3s/cluster-token" if [ ! -f "$TOKEN_FILE" ]; then echo "==> Generating k3s cluster token" sudo mkdir -p /var/lib/k3s head -c 32 /dev/urandom | base64 | sudo tee "$TOKEN_FILE" > /dev/null sudo chmod 600 "$TOKEN_FILE" fi # 2. Copy token to target node echo "==> Copying cluster token to $HOSTNAME" ssh "root@$TSIP" "mkdir -p /var/lib/k3s" scp "$TOKEN_FILE" "root@$TSIP:$TOKEN_FILE" # 3. Copy NixOS config echo "==> Copying NixOS configuration" ssh "root@$TSIP" "mkdir -p /etc/nixos/nodes /etc/nixos/modules" scp "$REPO_DIR/flake.nix" "root@$TSIP:/etc/nixos/flake.nix" scp "$REPO_DIR/hardware-n97.nix" "root@$TSIP:/etc/nixos/hardware-n97.nix" 2>/dev/null || true scp "$REPO_DIR/hardware-rpi4.nix" "root@$TSIP:/etc/nixos/hardware-rpi4.nix" 2>/dev/null || true scp "$REPO_DIR/modules/"*.nix "root@$TSIP:/etc/nixos/modules/" scp "$REPO_DIR/nodes/$HOSTNAME.nix" "root@$TSIP:/etc/nixos/nodes/" # 4. Build and switch echo "==> Building NixOS configuration for $HOSTNAME" ssh "root@$TSIP" "nixos-rebuild switch --flake /etc/nixos#$HOSTNAME" # 5. Wait for k3s to come up echo "==> Waiting for k3s to start..." sleep 10 if [ "$ROLE" = "server" ]; then echo "==> k3s server is running. Get kubeconfig:" echo " scp root@$TSIP:/etc/rancher/k3s/k3s.yaml ~/.kube/config-scobleclaw" echo " sed -i 's/127.0.0.1/$TSIP/g' ~/.kube/config-scobleclaw" else echo "==> k3s agent joined. Verify with: kubectl get nodes" fi echo "==> Done! $HOSTNAME is ready."