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>
128 lines
4.1 KiB
Plaintext
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
|