Compare commits
4 Commits
091f11f036
...
feature/us
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a6a0e39c3 | ||
|
|
d60bc96f1d | ||
|
|
f3e7c5d108 | ||
|
|
2370049e48 |
21
archive/maas/README.md
Normal file
21
archive/maas/README.md
Normal 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.
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user