#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