Add minimal autoinstall + first-boot.sh (fleet baseline, Docker, NFS, Tailscale)

This commit is contained in:
Artemis (Iron Legion)
2026-05-23 18:50:08 -04:00
parent 74c26b370b
commit 091f11f036
2 changed files with 183 additions and 0 deletions

88
autoinstall/first-boot.sh Normal file
View File

@@ -0,0 +1,88 @@
#!/bin/bash
# first-boot.sh — Iron Legion Fleet Node Post-Install Bootstrap
# Run manually AFTER confirming autoinstall boots successfully
# Date: May 23, 2026
set -euo pipefail
# ========== CONFIG ==========
TRUENAS_IP="192.168.16.254"
NFS_SHARE="/mnt/Ice/Backup/swarm-data"
LOCAL_MOUNT="/mnt/swarm-data"
ANSIBLE_REPO="https://gitea.nb.bobbysh.me/Iron-Legion/ansible-pull-deploy.git"
ANSIBLE_DIR="/var/lib/ansible/local"
TAILSCALE_API_KEY="${TAILSCALE_API_KEY:-}" # Set before running, or hardcode for unattended
# ========== DOCKER ==========
echo "[1/6] Installing Docker CE..."
if ! command -v docker >/dev/null 2>&1; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu noble stable" > /etc/apt/sources.list.d/docker.list
apt-get update
apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable docker
systemctl start docker
usermod -aG docker jarvis
echo "Docker installed."
else
echo "Docker already present."
fi
# ========== NFS AUTOMOUNT ==========
echo "[2/6] Configuring NFS automount for TrueNAS..."
mkdir -p "$LOCAL_MOUNT"
if ! grep -q "$TRUENAS_IP:$NFS_SHARE" /etc/fstab; then
echo "$TRUENAS_IP:$NFS_SHARE $LOCAL_MOUNT nfs defaults,_netdev 0 0" >> /etc/fstab
mount "$LOCAL_MOUNT"
echo "NFS mount added to fstab and mounted."
else
echo "NFS fstab entry already exists."
fi
# ========== ANSIBLE-PULL REPO ==========
echo "[3/6] Cloning ansible-pull repo..."
mkdir -p "$ANSIBLE_DIR"
if [ ! -d "$ANSIBLE_DIR/.git" ]; then
cd "$ANSIBLE_DIR"
git clone "$ANSIBLE_REPO" .
echo "Ansible repo cloned."
else
echo "Ansible repo already present."
fi
# ========== TAILSCALE ==========
echo "[4/6] Installing Tailscale..."
if ! command -v tailscale >/dev/null 2>&1; then
curl -fsSL https://tailscale.com/install.sh | sh
echo "Tailscale installed."
else
echo "Tailscale already present."
fi
if [ -n "$TAILSCALE_API_KEY" ]; then
echo "[5/6] Joining Tailnet..."
tailscale up --auth-key="$TAILSCALE_API_KEY" --ssh --accept-routes
echo "Tailscale joined."
else
echo "[5/6] TAILSCALE_API_KEY not set. Run manually:"
echo " export TAILSCALE_API_KEY=tskey-..."
echo " tailscale up --auth-key=\$TAILSCALE_API_KEY --ssh --accept-routes"
fi
# ========== ENABLE SERVICES ==========
echo "[6/6] Enabling services..."
systemctl enable ssh docker
systemctl restart ssh docker
# ========== DONE ==========
echo ""
echo "========================================"
echo " Fleet node bootstrap complete"
echo "========================================"
echo "Docker: $(docker --version)"
echo "Tailscale: $(tailscale version 2>/dev/null | head -1 || echo 'not joined')"
echo "NFS mount: $(df -h | grep swarm-data || echo 'not mounted')"
echo "Ansible: $(ansible --version | head -1 || echo 'not checked')"
echo ""
echo "Next: run ansible-pull from $ANSIBLE_DIR"
echo " cd $ANSIBLE_DIR && ansible-pull -d . -U $ANSIBLE_REPO"

View File

@@ -0,0 +1,95 @@
# Ubuntu Autoinstall — Iron Legion Fleet Standard (MINIMAL)
# Targets: GMKtec G9 N150, 1TB NVMe (/dev/nvme0n1)
# Date: May 23, 2026
# Role: Bare-metal bootable fleet node — manual post-install via first-boot.sh
version: 1
reporting:
builtin:
type: print
autoinstall:
identity:
hostname: fleet-node
username: jarvis
password: "$6$0DL8vh2WMWRpPiOt$xP1XyKFbX8J0hGSwd9GD6RsPAM5Ajdkrd8PYW2KJAv64YBJC3NAHgGr4BNYORodCVf1hkv3D2KhbezFoIlVsL1"
ssh:
install-server: true
authorized-keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPSBrRCROUHOiZX9IB3teEK89VFfghbdu7OF5NoJ1Y6g Generated By Termius
allow-pw: true
network:
version: 2
ethernets:
enp4s0:
dhcp4: true
optional: true
enp5s0:
dhcp4: true
optional: true
enp6s0:
dhcp4: true
optional: true
storage:
config:
- type: disk
id: nvme0n1
path: /dev/nvme0n1
ptable: gpt
wipe: superblock-recursive
- type: partition
id: boot-part
device: nvme0n1
size: 1GiB
flag: boot
- type: partition
id: root-part
device: nvme0n1
size: -1
- type: format
id: boot-format
volume: boot-part
fstype: ext4
- type: format
id: root-format
volume: root-part
fstype: ext4
- type: mount
id: boot-mount
device: boot-format
path: /boot
- type: mount
id: root-mount
device: root-format
path: /
swap:
size: 0
packages:
- openssh-server
- curl
- nfs-common
- cifs-utils
- net-tools
- ca-certificates
- gnupg
- ansible
- git
late-commands:
# Prevent cloud-init from stomping hostname on first boot
- echo 'preserve_hostname: true' > /target/etc/cloud/cloud.cfg.d/99_preserve_hostname.cfg
# Add jarvis to sudoers with NOPASSWD
- echo 'jarvis ALL=(ALL) NOPASSWD: ALL' > /target/etc/sudoers.d/jarvis
- chmod 440 /target/etc/sudoers.d/jarvis
# Ensure SSH key has correct permissions
- chmod 600 /target/home/jarvis/.ssh/authorized_keys
- chown -R 1000:1000 /target/home/jarvis/.ssh
# Auto-reboot after install completes
shutdown: reboot