Compare commits

..

4 Commits

Author SHA1 Message Date
Artemis (Iron Legion)
9a6a0e39c3 Revert "Add homelab services stack PRD"
This reverts commit d60bc96f1d.
2026-05-25 17:58:43 -04:00
Artemis (Iron Legion)
d60bc96f1d Add homelab services stack PRD
Verifies 16 DockerHub images, assigns target nodes per locked policy,
defines 3-phase deployment order (Infra → Media → Polish),
and captures open questions for Bobby.

Services: Traefik, Technitium DNS, AdGuard Home, Prometheus, Grafana,
Beszel, Dozzle, Portainer, Homepage, Authelia, Vaultwarden, Jellyfin,
Sonarr, Radarr, Prowlarr, Nextcloud

Domain: *.ai.home
No public internet exposure.
2026-05-25 17:17:23 -04:00
Artemis (Iron Legion)
f3e7c5d108 Move autoinstall/ to 412friendly/backups.git (staging repo) — Iron-Legion repo is ansible-pull only 2026-05-23 19:01:30 -04:00
Artemis (Iron Legion)
2370049e48 Archive MAAS preseed to archive/maas/ with README — project abandoned, replaced by USB autoinstall 2026-05-23 18:58:46 -04:00
5 changed files with 21 additions and 309 deletions

21
archive/maas/README.md Normal file
View File

@@ -0,0 +1,21 @@
# MAAS Archive
**Status: ABANDONED — May 23, 2026**
These files are the final state of the MAAS PXE deployment effort for Iron Legion fleet nodes. MAAS was removed from Shield after repeated failures on isolated subnets, IP exhaustion, and general complexity. Replaced by USB autoinstall approach.
## Files
- `curtin_userdata_fleet_v5.yaml` — Fleet preseed targeting `/dev/nvme0n1`, no apt-get (isolated subnet safe), SSH enable only. Final working version before abandonment.
## Lessons Captured
1. MAAS ephemeral commissioning fails on subnets without internet (apt-get hangs)
2. IP exhaustion on /27 pools after failed deployments (sticky reservations)
3. G9 Intel I226-V NIC (enp5s0) drops link during Linux driver init
4. Linux enumerates first NVMe as `nvme0n1`, not `nvme1`
5. Cloud-init stomps hostname unless `preserve_hostname: true` is set
## Replacement
See `autoinstall/` in repo root for the USB-based replacement workflow.

View File

@@ -1,88 +0,0 @@
#!/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

@@ -1,95 +0,0 @@
# 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

View File

@@ -1,126 +0,0 @@
# Ubuntu Autoinstall Template — Iron Legion Fleet Standard
# Generated May 23, 2026. Targets GMKtec G9 N150, 1TB NVMe (/dev/nvme0n1)
# Includes: jarvis user, SSH key, Docker, NFS client, Tailscale (optional)
version: 1
reporting:
builtin:
type: print
autoinstall:
identity:
hostname: ubuntu-fleet-node
username: jarvis
password: "$6$rounds=5000$fleet$salts$hashedpassword"
# ^^^ Generate with: mkpasswd -m sha-512 ubuntu
# Or use: python3 -c "import crypt; print(crypt.crypt('ubuntu', crypt.mksalt(crypt.METHOD_SHA512)))"
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
# Note: enp5s0 is the Intel I226-V which drops link on some G9 units.
# Fallback to enp4s0 if enp5s0 fails.
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
late-commands:
# Fix hostname preservation (cloud-init stomp bug)
- echo 'preserve_hostname: true' > /target/etc/cloud/cloud.cfg.d/99_preserve_hostname.cfg
# Set hostname explicitly
- hostnamectl set-hostname ubuntu-fleet-node
# Add jarvis to sudoers with NOPASSWD
- echo 'jarvis ALL=(ALL) NOPASSWD: ALL' > /target/etc/sudoers.d/jarvis
- chmod 440 /target/etc/sudoers.d/jarvis
# Create SSH directory and inject key (fallback if ssh section fails)
- mkdir -p /target/home/jarvis/.ssh
- echo 'ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPSBrRCROUHOiZX9IB3teEK89VFfghbdu7OF5NoJ1Y6g Generated By Termius' > /target/home/jarvis/.ssh/authorized_keys
- chmod 600 /target/home/jarvis/.ssh/authorized_keys
- chown -R 1000:1000 /target/home/jarvis/.ssh
# Install Docker
- 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" > /target/etc/apt/sources.list.d/docker.list
- curtin in-target -- apt-get update
- curtin in-target -- apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add jarvis to docker group
- usermod -aG docker jarvis
# Enable and start services
- systemctl enable docker
- systemctl enable ssh
# Install Tailscale (optional — needs auth key for auto-join)
# Uncomment and add TAILSCALE_AUTH_KEY to user-data if auto-join desired
# - curl -fsSL https://tailscale.com/install.sh | sh
# - tailscale up --auth-key=${TAILSCALE_AUTH_KEY}
# Clone ansible-pull repo (optional — needs git and network)
# - mkdir -p /target/var/lib/ansible/local
# - cd /target/var/lib/ansible/local && git clone https://gitea.nb.bobbysh.me/Iron-Legion/ansible-pull-deploy.git .
# Re-enable netplan for actual NIC that comes up
- sed -i 's/optional: true/optional: false/g' /target/etc/netplan/00-installer-config.yaml 2>/dev/null || true
# Shutdown after install (remove for auto-reboot)
# shutdown: reboot