A question that continues to pop up from time to time is whether it is possible to prompt for user input during an interactive or scripted installation of ESXi? This is actually something I have written about before using PXE boot options as a workaround to provide for a semi-interactive automated installation of ESXi. The most recent request for this was not actually from a customer but rather someone internally working at VMware. The individual noted that he had already read my blog and a few other references but was still hopeful for a solution. I remember when I had looked into this problem several years back, I was not able to find anything and the inquiries to VMware (which I was still a customer at the time) came up empty.
UPDATE (01/10/19) - For ESXi 6.5 or greater, please take a look at this blog post for an updated solution
After replying back to the individual with the information that I had, it actually got me thinking which is usually not good 😉 Having just recently finished building a new Kickstart environment to test UEFI PXE boot for ESXi 6.0, I figure I might as well take another look at this topic again. I wanted to see if there was something that could be done with one of the /dev/ttyl (teletype) interfaces while the ESXi Installation was running. I did a couple of Google searches and to my surprise, there was someone on the VMTN Community forum who had already solved this problem and posted a solution almost 1 year before my article, not sure how I could have missed that?!
In ESXi, there are only two TTY interfaces: TTY1 (/dev/tty1) and TTY2 (/dev/tty2) and during the installation of ESXi, /dev/tty2 is used by the interactive installer and /dev/tty1 is used by the ESXi Shell login for troubleshooting/debugging purposes. If you try to overlay another menu system on top of the existing one, what you will find is that although it is possible to prompt for user input, the user keystrokes would not be properly being sent due to having two menus as mentioned by VMTN Community user mossko. The clever solution that was identified by cacheman was to simply disable the console login and free up TTY1 which could then be used to present a custom menu and prompt for user input. This was accomplished by creating a custom TGZ file called "extras.tgz" (you can name it anything you want) which would contain a modified copy of the /etc/inittab file which has the following line commented out:
#tty1::respawn:/bin/initterm.sh tty1 /bin/techsupport.sh
You would then append this TGZ to the ESXi's boot.cfg file which would then overwrite the existing inittab and prevent ESXi Shell from running on TTY1. I thought this was very cool way of solving this problem, nice work and thanks for sharing cacheman!
I wanted to verify that this solution still works with the latest release of ESXi 6.0 Update 1 and luckily it still does and here is a sample menu prompt that I created which prompts users for the networking settings for the ESXi host which will then be used by the ESXi Kickstart script. This is just one example of user prompts that can be created, this is only limited by your imagination and the amount of input you wish to put your users through 😉 If you are interested in the ASCII art, go to the very bottom for the full details.
Here are the exact instructions along with the sample menu that was used in the screenshot above.
Step 1 - Create a temporary directory which will be used to store our modified inittab file by running the following command:
mkdir -p temp/etc
Step 2 - Change into the "temp" directory
Step 3 - Copy the /etc/inittab file into the etc directory and you should have the following: temp/etc/inittab
Step 3 - Edit the etc/inittab file and comment out the following line:
#tty1::respawn:/bin/initterm.sh tty1 /bin/techsupport.sh
Step 4 - Next, we need to create a TGZ file of the etc directory by running the following command:
tar -czvf extras.tgz etc
Step 5 - Copy the extras.tgz to root of your ESXi installation if you are PXE booting or if you are re-authoring a new ESXi ISO
Step 6 - Edit the ESXi's boot.cfg configuration file and append the following after imgpayld.tgz:
--- extras.tgz
Step 7 - Finally, you will add your custom menu prompt into the %pre section of an ESXi Kickstart file. Below is an example Kickstart that I used to build the menu shown in the screenshot above.
accepteula install --firstdisk --overwritevmfs rootpw vmware123 reboot %include /tmp/networkconfig %pre --interpreter=busybox exec < /dev/tty1 > /dev/tty1 2>&1 chvt 1 HOSTNAME="" IPADDR="" NETMASK="" GATEWAY="" DNS="" while [[ "$HOSTNAME" == "" ]] || [[ "${IPADDR}" == "" ]] || [[ "${NETMASK}" == "" ]] || [[ "${GATEWAY}" == "" ]] || [[ "${DNS}" == "" ]] ; do echo echo " *** Please enter the following details: *** " echo read -p "Hostname: " HOSTNAME read -p "IP Address: " IPADDR read -p "Netmask: " NETMASK read -p "Gateway: " GATEWAY read -p "DNS: " DNS done clear echo "network --bootproto=static --addvmportgroup=true --device=vmnic0 --ip=${IPADDR} --netmask=${NETMASK} --gateway=${GATEWAY} --nameserver=${DNS} --hostname=${HOSTNAME}" > /tmp/networkconfig echo -e "Applying the following configuration: \n" echo "Hostname = ${HOSTNAME}" echo "IP Address = ${IPADDR}" echo "Netmask = ${NETMASK}" echo "Gateway = ${GATEWAY}" echo -e "DNS = ${DNS}\n" sleep 5 chvt 2 %firstboot --interpreter=busybox sed -i 's/#tty1/tty1/g' /etc/inittab /sbin/auto-backup.sh vim-cmd hostsvc/enable_ssh vim-cmd hostsvc/start_ssh vim-cmd hostsvc/enable_esx_shell vim-cmd hostsvc/start_esx_shell
Lines 10-11 - Redirects the output to /dev/ttyl and changes to tty1 virtual console.
Lines 12-16 - Define a couple of empty string variables that will be used to store user input.
Lines 18-28 - Prompt user input and loop until all variables are not empty.
Lines 30 - Using the user input, generate the networking configuration for the ESXi Kickstart.
Line 32-38 - Display the user input to the user and sleep for 5 seconds before switching back to the ESXi installer.
Line 39 - Change to /dev/tty2 virtual console which will show the regular ESXi installer menu.
Line 43-44 - Modify the /etc/inittab to re-enable ESXi Shell for /dev/tty1. For the changes to go into effect, you will need reboot and you can either do this when you need the capability (which is not ideal) or you can just automatically issue a second reboot in the %firstboot section of the Kickstart, so the ESXi Shell is available when you need it.
For those interested in how I added the ASCII art, I used this site here to generate the text. Once you are happy with the text and how it is displayed, which may require several rounds of testing, you will then want to save it to a file. In my setup I just called it vg-ascii.cfg and this should be placed on either your HTTP Server where the Kickstart is being pulled or embedded into the ESXi ISO if you are doing local installs only. You will then need to add the following lines to the "pre" section of the Kickstart right before the loading of the menu prompt. In this example, I am downloading the ASCII file from my web server which is also serving my kickstart and then clearing the screen before iterating through the file to display the text.
wget http://192.168.1.180/esxi60u1/vg-ascii.cfg -O /tmp/vg-ascii.cfg
clear
IFS=$'\n';for i in $(cat /tmp/vg-ascii.cfg);do echo $i;done
Burvil says
Thanks for your post. That's some really neat information. Some questions --
1. Any reason this can't be done with python as the interpreter? It seems busybox is basically a shell, and usual shell script syntax would pretty much apply, so I'd think things are simpler with an interpreter, but more flexible with python.
2. I take it these variables that are read in can then be used to configure the network without any further manipulation, i.e. no instantiation of class instances, etc.?
3. Do you know if this method would be fully supported by VMware?
4. Since the /dev/ttyl1 console is accessible via Alt+F1, would'nt the user have to press those key combinations to see the prompt? Seems like that's implied, but not sure.
William Lam says
Re 1: No reason, just wanted a simple example but you can use either
Re 2: Correct, please refer to line 32 for the details
Re 3: I can't comment on supportability but since we're modifying default configuration files, its possible you may be asked to disable this for troubleshooting purposes
Re 4: No, that's why there's line 13 & 41 which changes between the different consoles
Erwin says
Hi William, do you know if this still works with ESXi 6.5? I am trying hard to get it to work but it doesn't seem to work anymore. I always get the login prompt and password. The KS script works because I am getting the questions. If I look at the etc/inittab the line is commented with a #. Still getting the login prompt which corrupts the input and makes things very slow.
Thanks
someguy says
This is much more graceful idea than what I did. I have a tftp kickstart server which also runs a web server. If I get asked to install ESXi with specific variables for a customer, I use a web form with fields for this. A PHP script then creates a new custom kickstart config from templates. 99% of whats in the config is the same between each install so this seemed the best way to do it at the time. Only downside is you end up with a bunch of extra KS configs that you may only use once.
benjamin rualthanzauva says
Thanks Liam for this tip. Exactly what I need and I have just built an ISO and tested it.
1) you got to enter the values right at first shot. Otherwise other keystrokes invalidates the value halting the install process
2) Probably a stupid question, how does /tmp/networkconfig magic work?
Jeff Smith says
So how would you store variables across to first boot? I tried the ESXI_INSTALL_LOG method from the previous example but that errors out during boot.
Matt says
I would like to know how to do this also. My current automated build has a few different variables that inputted. How do we use this and pass them to a log file so the variables can be extracted and used in the %post section.
Matt says
I was able to get this to work my simply echoing the variables to a log file.
Example:
INSTALL_LOG=/var/log/esxi_install.log
echo "IPADDR ${IPADDR}" >> ${INSTALL_LOG}
echo "NETMASK ${NETMASK}" >> ${INSTALL_LOG}
echo "GATEWAY ${GATEWAY}" >> ${INSTALL_LOG}
Will in ATX says
Great info! Speaking of interesting tricks with ESXi kickstart... Is there a way to avoid setting the root password when kickstarting ESXi 6.0? I have a need to pre-stage ESXi6 on a bunch of servers which will be sent out into the field. I'd like the admin who gets any one of these servers to be able to choose a root password at first boot. I'm pretty sure I used to be able to do this in 5.x. Thanks!!!
Cisco Lyon says
Hi,
I want to change /etc/inittab on my esxi 6.0.0 but I failed
echo \# ca::ctrlaltdel:/sbin/shutdown -t3 -r now >> /etc/inittab
-sh: can't create /etc/inittab: Operation not permitted
With vi it is the same problem.
any good idea
https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1018950
all the best
Anil says
Hi,
This works great!! however post reboot it's challenging "Authentication" Localhost login: , It doesn't accept predefined password, any ideas? ( using ESXi 6.0.0)
Thanks in advance
Anil
i says
you can use root as login and empty password (just press enter)
Anil says
Thanks You,
Doesn't work either,
Tim Ye says
hi, work great. but i cannot get ASCII art to work!
%pre --interpreter=busybox
#wget cdrom:/KS/LOGO.CFG -O /tmp/vg-ascii.cfg
#clear
#IFS=$'\n';for i in $(cat /tmp/vg-ascii.cfg);do echo $i;done
exec /dev/tty1 2>&1
chvt 1
wget cdrom:/KS/LOGO.CFG -O /tmp/vg-ascii.cfg
#wget /KS/LOGO.CFG -O /tmp/vg-ascii.cfg
clear
IFS=$'\n';for i in $(cat /tmp/vg-ascii.cfg);do echo $i;done
do you know why?
Tim says
also the delete, backspace and allow keys did not work when I tried to modify, tried read -e but failed, illegal option. Anyone know how to delete or backspace?
Yanick says
Hi William,
Thanks for this tuto. I'm new on VMware and I'm looking for a way to do an automatic esx deployment by reading some information (hostname, IP address...) from text file.
Derek says
Hi, in vSphere 6.5 it needs login (on tty1 in this case) first while prompting for user input.
Could you please help to check how to fix it?
Scott says
This was working up to 6.0 but in 6.5 it no longer works as other people have stated, the try is now used for a login prompt at build time. Any ideas on how to get around this? I have tried to disable the prompt but no joy thus far
sajag007 says
HI William I am new to VMWare as i tried all the above steps given by you still it didn't work for me it will be highly appreciated if you can help
Thanks
SJ
James Price says
Hi William, thanks for this article its great! but as you may have read its not working as designed on esxi 6 and newer. Any chance you might revisit this topic for the newest versions? We're trying to automate our deployments for our customers by pre-loading esxi and some vms via a kick start. Obviously the ip config is different for each customer, so this would be really helpful to us.
Thanks,
James
Burvil Chang says
Any update on getting this to work in ESXi 6.5?
Anthony Amodei says
I've been working the ESXi 6.5 route, but to no avail as of yet. I feel that if we could somehow programmatically answer the login prompt since the ESXi shell needs a login first, that might do the trick, but I'm still working on it
Bryan A says
I watched during boot and noticed that the extras.tgz file does not get loaded during the installation on 6.7. I am TFTP booting and pointing to boot.cfg in my ESXi image and have extras.tgz listed, but it is still not pulling the changed file. I believe this might be the problem that everyone is running into on 6.5 and up, but I do not know where to go from here. Hopefully this helps move the ball along so we can find an answer.
snir says
Any update on getting this (or any other way) to work in ESXi 6.5?