In the second part, we take a look at the PHP scripts that will generate the necessary files to boot our servers as well as how to get all the needed information and data to successfully install an ESXi Host.
For ease of understanding, I´ll start with a “fake database” PHP file.
As I can´t give the code for our database backend I´ve created this fake script to show the idea behind the whole thing.
database_fake.php
The script takes the submitted UUID of the server and fills all variables needed for the installation of the OS. In this example, it´s all for VMware ESXi 8.0 Update 3.
<?php
//convert UUID to uppercase
if(isset($_GET['uuid'])) {
$uuid = strtoupper($_GET['uuid']);
}
##general settings
$domain_name = "sddc.local";
if($uuid == "E7D71F42-8EEF-DD93-1312-EC6A1A207ED4") {
$ipaddress = "172.28.0.11";
$netmask = "255.255.255.0";
$gateway = "172.28.0.254";
$nameserver = "172.28.0.254";
$hostname = "esx-vcf-mgmt01";
$fqdn = $hostname.".".$domain_name;
$vlanid = "1611";
$os = "esx8u3_24022510";
$install_disk_name = "mpx.vmhba0:C0:T0:L0";
}
if($uuid == "E4C21F42-9AA6-45E6-915A-64049CD484E0") {
$ipaddress = "172.28.0.12";
$netmask = "255.255.255.0";
$gateway = "172.28.0.254";
$nameserver = "172.28.0.254";
$hostname = "esx-vcf-mgmt02";
$fqdn = $hostname.".".$domain_name;
$vlanid = "1611";
$os = "esx8u3_24022510";
$install_disk_name = "mpx.vmhba0:C0:T0:L0";
}
?>
multiboot.php
This file serves as entrypoint to all other steps during the provisioning.
Here we decide which Operating System will be installed on the system and pass the bootloader information to the server.
<?php
//set output to plain text to avoid problems with html code in the boot process
header('Content-Type: text/plain');
include "database_fake.php";
if($os == "esx8u3_24022510") {
echo "#!ipxe
kernel http://<ip of webserver>/os_data/esx8u3_hpe_24022510/efi/boot/bootx64.efi -c http://<ip of webserver>/esx8_bootloader.php?uuid=$uuid
boot";
}
if($os == "Red Hat Enterprise Linux 9") {
echo "#!ipxe
initrd http://<ip of webserver>/os_data/rhel9/images/pxeboot/initrd.img
chain http://<ip of webserver>/os_data/rhel9/images/pxeboot/vmlinuz initrd=initrd.img inst.ks=http://<ip of webserver>/rhel9_ks.php?uuid=".$uuid." inst.gpt ip=dhcp
";
}
?>
In case of ESXi we take an extra loop with the esx8_bootloader.php file, as for RHEL9 we directly the installer and only passing over the rhel9_ks.php file.
The installation of RHEL9 will be the topic for another article.
This series will only handle the installation of ESXi.
esx8_bootloader.php
The task for the esx8_bootloader.php script is to emulate the boot.cfg file you find on the ESXi installation ISO file.
Therefore most of this data comes directly from the ESXi ISO file and the process of preparation is also almost the same as for a PXE installation.
First, mount the ISO file and copy all files including subfolders to a location on your web server, in my case, I`ve stored everything under os_data/esx8u3_hpe_24022510.
Then open boot.cfg from that folder and copy everything to your bootloader PHP script. In the modules and kernel part remove all “/”, otherwise the changed prefix will not work. Change the prefix part to point to the place where you´ve placed all the files from the ISO.
Be aware that from release to release the files in the modules section can change, so be sure to always copy the matching version from the boot.cfg file.
<?php
//set output to plain text to avoid problems with html code in the boot process
header('Content-Type: text/plain');
include "database_fake.php";
if($os == "esx8u3_24022510") {
echo "
bootstate=0
title=Loading ESXi installer
timeout=0
prefix=http://<ip of webserver>/os_data/esx8u3_hpe_24022510/
kernel=b.b00
kernelopt=ks=http://<ip of webserver>/esx8_ks.php?uuid=".$uuid." nameserver=".$nameserver." ip=".$ipaddress." netmask=".$netmask." gateway=".$gateway." vlanid=".$vlanid."
modules=jumpstrt.gz --- useropts.gz --- features.gz --- k.b00 --- uc_intel.b00 --- uc_amd.b00 --- uc_hygon.b00 --- procfs.b00 --- vmx.v00 --- vim.v00 --- tpm.v00 --- sb.v00 --- s.v00 --- bnxtnet.v00 --- bnxtroce.v00 --- amsd.v00 --- amsdv.v00 --- stage.v00 --- payload.v00 --- ilo.v00 --- ilorest.v00 --- sut.v00 --- i40en.v00 --- iavmd.v00 --- icen.v00 --- igbn.v00 --- ixgben.v00 --- mft_oem.v00 --- mft.v00 --- nmst.v00 --- ssacli.v00 --- qlnative.v00 --- qcnic.v00 --- qedentv.v00 --- qedf.v00 --- qedi.v00 --- qedrntv.v00 --- qfle3.v00 --- qfle3f.v00 --- qfle3i.v00 --- atlantic.v00 --- bcm_mpi3.v00 --- brcmfcoe.v00 --- cndi_igc.v00 --- dwi2c.v00 --- elxiscsi.v00 --- elxnet.v00 --- intelgpi.v00 --- ionic_cl.v00 --- ionic_en.v00 --- irdman.v00 --- iser.v00 --- lpfc.v00 --- lpnic.v00 --- lsi_mr3.v00 --- lsi_msgp.v00 --- lsi_msgp.v01 --- lsi_msgp.v02 --- mtip32xx.v00 --- ne1000.v00 --- nenic.v00 --- nfnic.v00 --- nhpsa.v00 --- nipmi.v00 --- nmlx5_cc.v00 --- nmlx5_co.v00 --- nmlx5_rd.v00 --- ntg3.v00 --- nvme_pci.v00 --- nvmerdma.v00 --- nvmetcp.v00 --- nvmxnet3.v00 --- nvmxnet3.v01 --- pvscsi.v00 --- qflge.v00 --- rdmahl.v00 --- rste.v00 --- sfvmk.v00 --- smartpqi.v00 --- vmkata.v00 --- vmksdhci.v00 --- vmkusb.v00 --- vmw_ahci.v00 --- bmcal.v00 --- clusters.v00 --- crx.v00 --- drivervm.v00 --- elx_esx_.v00 --- btldr.v00 --- dvfilter.v00 --- esx_ui.v00 --- esxupdt.v00 --- tpmesxup.v00 --- weaselin.v00 --- esxio_co.v00 --- infravis.v00 --- loadesx.v00 --- lsuv2_hp.v00 --- lsuv2_in.v00 --- lsuv2_ls.v00 --- lsuv2_nv.v00 --- lsuv2_oe.v00 --- lsuv2_oe.v01 --- lsuv2_sm.v00 --- native_m.v00 --- trx.v00 --- vcls_pod.v00 --- vdfs.v00 --- vds_vsip.v00 --- vmware_e.v00 --- hbrsrv.v00 --- vsan.v00 --- vsanheal.v00 --- vsanmgmt.v00 --- tools.t00 --- xorg.v00 --- gc.v00 --- imgdb.tgz --- basemisc.tgz --- resvibs.tgz --- esxiodpt.tgz --- imgpayld.tgz
updated=0
";
}
?>
esx8_ks.php
The final part of the installation process is the execution of the installation handled by the kickstarter. If you already have working kickstart files you can copy and adept your data within this script.
In my example the kickstart will prepare the ESXi Host to be part of a VCF installation.
Things handled by the kickstart example file:
– Accept the EULA.
– set a root password.
– clear all partitions.
– read the install command from a file which is created during PRE-installation phase.
– set network according to fake database values.
– Run a PRE script to find the installation disk by name coming from fake database (you could also change this to look for a specific disksize or other things).
– Set DNS search suffix
– Configure NTP
– Disable CEIP
– Set keyboard to german
– Enable SSH
<?php
header('Content-Type: text/plain');
include "database_fake.php";
echo'### Accept the VMware End User License Agreement
vmaccepteula
rootpw VMware1!VMware1!
clearpart --alldrives --overwritevmfs
%include /tmp/DiskConfig
### Set the network
network --bootproto=static --ip='.$ipaddress.' --netmask='.$netmask.' --gateway='.$gateway.' --nameserver='.$nameserver.' --hostname='.$fqdn.' --addvmportgroup=0 --vlanid='.$vlanid.'
### Reboot ESXi Host
reboot
##### Stage PRE installation:
%pre --interpreter=busybox
echo "DISK=`ls /vmfs/devices/disks|grep -E '^".$install_disk_name."$'`";
echo "install --disk=$DISK --overwritevmfs --novmfsondisk --forceunsupportedinstall">/tmp/DiskConfig
##### Stage FIRSTBOOT:
### Open busybox and launch commands
%firstboot --interpreter=busybox
### Set Search Domain
esxcli network ip dns search add --domain=sddc.local
### Configure NTP
esxcli system ntp set -e true -s 0.de.pool.ntp.org -s 1.de.pool.ntp.org
/sbin/chkconfig ntpd on
esxcli system ntp set --enabled=yes
### Disable CEIP
esxcli system settings advanced set -o /UserVars/HostClientCEIPOptIn -i 2
### change keyboard layout to german
esxcli system settings keyboard layout set -l German
# Enable SSH
vim-cmd hostsvc/enable_ssh
vim-cmd hostsvc/start_ssh
'
?>
That´s all for today, now you have everything to install many ESXi hosts.
Leave a Reply