Background:
Foreman does not support ESXi natively. While the legacy BIOS mode installation is simple enough using “PXELinux BIOS” as the bootloader, installation in EFI mode is much trickier. Problem is exacerbated by GRUB2 not being able to chainload the ESXi EFI bootloader mboot.efi (a renamed bootx64.efi).
For EFI mode installation, you have to pass the filename = mboot.efi directive from the dhcp server to the client. So you dit dhcpd.conf, change the loader to mboot.efi and change the PXELoader of the host to “None”. Now you have managed to install ESXi successfully using foreman. However when the client reboots, it tries to PXE boot again. Once it loads mboot.efi, it will try to reinstall the OS. There are ways to stop the actual installation from happening but you cannot perform a local boot and the host will never boot inside ESXi. This is in stark contrast to legacy BIOS mode where after installation completes and client does a PXE boot, it is presented with the default PXELinux template and the first entry is LOCALBOOT.
Workaround(s):
- Don’t have NIC as the first boot entry and use host specific scripts to set one time PXE boot.
- Through Foreman:
So it’s evident that you cannot have dhcpd.conf hand out mboot.efi. It needs to be controlled on a per host basis through dhcpd.leases file. To have a completely automated workflow, I thought about this:
ESXi installation in EFI mode:
- Set host’s PXELoader to None
- Create after_build foreman-hook script which checks OS Name, PXELoader and host mac.
- If OS_Name starts with ‘ESXi’ and PXELoader = ‘None’
- Edit the latest entry of the host in dhcpd.leases and set filename = mboot.efi
- Reload dhcp server
- Next create a before_provision script with same checks as above
- Delete the filename directive of the host from lease file.
- Reload dhcp server
- Turn off build mode for the host as the wget foreman-built call will fail.
Problem:
The after_build script is not able to edit the dhcp lease file. Here’s the snippet:
dhcpleasefile="/var/lib/dhcp/dhcpd.leases"
active_lease_mac_line_no=$(grep -n $system_mac $dhcpleasefile |tail -1 |awk -F: '{print $1}')
echo "Last entry of $system_mac found at line number $active_lease_mac_line_no in dhcpd.leases"
pxe_loader_line=$(tail -n+$((active_lease_mac_line_no+2)) $dhcpleasefile | head -1)
if [[ $pxe_loader_line != *"server.filename"* ]]; then
echo "Line $((active_lease_mac_line_no+2)) = ${pxe_loader_line}. No PXE Loader"
sed -i $((active_lease_mac_line_no+2))i'\ supersede server.filename = "mboot.efi";' $dhcpleasefile
else
echo "PXE-Loader exists"
fi
Error message:
sed: couldn't open temporary file /var/lib/dhcp/sed6gplUv: Permission denied
Is there a better solution? If not, is there a workaround to edit the lease file or am I just sick outta luck?