Files
pxe-server/autoinstall/user-data
cproudlock a4abd238de Harden cloud-init disable and rebuild ISO properly in build-usb
Autoinstall user-data now disables cloud-init in multiple stages
(late-commands + runcmd + systemd masks) to prevent post-install
hangs. Also disables networkd-wait-online for air-gapped networks.
build-usb.sh switched from in-place ISO patching to full extract
and rebuild with xorriso mkisofs for reliable UEFI boot.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-14 10:53:26 -05:00

128 lines
4.1 KiB
Plaintext

#cloud-config
autoinstall:
version: 1
# Locale, keyboard, timezone
locale: en_US.UTF-8
keyboard:
layout: us
variant: ""
timezone: America/New_York
# Network: static IP for isolated PXE LAN (no internet/DHCP needed)
network:
version: 2
ethernets:
any-eth:
match:
name: "en*"
addresses:
- 10.9.100.1/24
dhcp4: false
dhcp6: false
optional: true
# Storage configuration
storage:
layout:
name: lvm
match:
size: largest
swap:
size: 0
# User identity
identity:
hostname: pxeserver
username: pxe
password: '$6$8AerqUockJh6ycgl$HJFBYjiFqXpzgcU9edto4CMrnaDpEX71Epin.kNTpj57GVjimIDHhcQs0AC4tmkEkKUaj.S/55wsBfMsV0KC71'
# Enable SSH
ssh:
install-server: true
allow-pw: true
# Installer-stage late commands
late-commands:
# Install deb packages from CIDATA USB, then disable cloud-init
- |
curtin in-target --target=/target -- bash -c '
mkdir -p /mnt/cidata
CIDATA_DEV=$(blkid -L CIDATA)
if [ -n "$CIDATA_DEV" ]; then
mount "$CIDATA_DEV" /mnt/cidata
if compgen -G "/mnt/cidata/packages/*.deb" > /dev/null; then
cp /mnt/cidata/packages/*.deb /tmp/
dpkg -i /tmp/*.deb 2>/dev/null || true
dpkg -i /tmp/*.deb 2>/dev/null || true
if command -v nmcli >/dev/null; then
systemctl enable NetworkManager
fi
fi
umount /mnt/cidata
fi
# Disable cloud-init AFTER dpkg (dpkg may overwrite earlier disables)
mkdir -p /etc/cloud
touch /etc/cloud/cloud-init.disabled
ln -sf /dev/null /etc/systemd/system/cloud-init.service
ln -sf /dev/null /etc/systemd/system/cloud-init-local.service
ln -sf /dev/null /etc/systemd/system/cloud-config.service
ln -sf /dev/null /etc/systemd/system/cloud-final.service
ln -sf /dev/null /etc/systemd/system/cloud-init.target
# Disable networkd-wait-online (no gateway on air-gapped network, causes 2min hang)
ln -sf /dev/null /etc/systemd/system/systemd-networkd-wait-online.service
'
# Create first-boot.sh + disable cloud-init (in same block we know works)
- |
curtin in-target --target=/target -- bash -c '
mkdir -p /etc/cloud/cloud.cfg.d
echo "datasource_list: [None]" > /etc/cloud/cloud.cfg.d/99-nocloud.cfg
touch /etc/cloud/cloud-init.disabled
ln -sf /dev/null /etc/systemd/system/systemd-networkd-wait-online.service
cat <<"EOF" > /opt/first-boot.sh
#!/bin/bash
CIDATA_DEV=$(blkid -L CIDATA)
if [ -n "$CIDATA_DEV" ]; then
mkdir -p /mnt/usb
mount "$CIDATA_DEV" /mnt/usb
# Install all offline .deb packages (ansible, dnsmasq, apache2, samba, etc.)
if compgen -G "/mnt/usb/packages/*.deb" > /dev/null; then
dpkg -i /mnt/usb/packages/*.deb 2>/dev/null || true
dpkg -i /mnt/usb/packages/*.deb 2>/dev/null || true
fi
# Run the Ansible playbook
if [ -f /mnt/usb/playbook/pxe_server_setup.yml ]; then
cd /mnt/usb/playbook
ansible-playbook -i localhost, -c local pxe_server_setup.yml
fi
umount /mnt/usb
fi
# Disable rc.local to prevent rerunning
sed -i "s|^/opt/first-boot.sh.*|# &|" /etc/rc.local
lvextend -r -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lv || true
EOF
'
- curtin in-target --target=/target -- chmod +x /opt/first-boot.sh
# Create rc.local without unintended indentation
- |
curtin in-target --target=/target -- bash -c '
cat <<"EOF" > /etc/rc.local
#!/bin/bash
/opt/first-boot.sh > /var/log/first-boot.log 2>&1 &
exit 0
EOF
'
- curtin in-target --target=/target -- chmod +x /etc/rc.local
user-data:
disable_root: false
runcmd:
- touch /etc/cloud/cloud-init.disabled
- systemctl disable cloud-init.service cloud-init-local.service cloud-config.service cloud-final.service
- systemctl mask cloud-init.service cloud-init-local.service cloud-config.service cloud-final.service
refresh-installer:
update: no