April 19, 2009

The Ultimate Kickstart File - Part 3

In the third and final chapter of our kickstart adventure, we're going to confront a scenario that would be a nightmare without a kickstart process in place: install and configure 100 ESX hosts. Good thing we've got our kickstart file dialed, because there is no way we're going to do that by hand. But we're still looking at some serious work in the UDA web console, adding 100 templates is a lot of clicks and copy and paste operations.

Thankfully, the UDA configuration files are pretty straightforward and easy to manipulate through the file system, and the underlying operating system is Fedora, so all the tools we need are available. Each individual UDA template is a plain text file with a .cfg extension, and they are stored in the /var/public/www/kickstart folder. The index file for the templates, /var/public/conf/templates.conf, is also a text file and can be directly edited with vi or modified from a shell script.

If you've been following this series, and have your kickstarts configured so that the only item that needs to be changed is the hostname, then the strategy is fairly simple:
  • Duplicate the master template .cfg file 100 times

  • Update the one configuration item in each template, the hostname

  • Add the 100 templates to the /var/public/conf/templates.conf file

Prep the master template
We're going to use sed to replace the hostname parameter in each template, so in the master template, use a marker that stands out from anything in the script. In this example we'll change esx02.vmnet.local from the kickstart script in Part 2 to 00HOSTNAME00.vmnet.local to make it easy to filter. Also, we don't want to overwrite our master template during this process, so make sure you give the master template a name that is not going to be in the range of names for the 100 cloned templates.

Make sure the perl regular expression you use to get the HOSTIP index works for the naming scheme you are going to use. In this example, we'll be naming the hosts pdx-labXXX.vmnet.local, and with the dash in there, the perl one-liner we wrote in Part 1 is not going to match. We need to change it in the master template to read:

HOSTIP=`/usr/bin/perl -e 'use Sys::Hostname; hostname() =~ /^[a-z-A-Z]+([0-9]+)\.?.*/ ; printf "%d", $1'`

The one-liner will now account for the dash by just adding it between the 'a-z' and 'A-Z'. It's a good idea to always test this out before committing to using a master template because if it doesn't get the IP from the hostname, the install is going to fail in a big way. Test out a few hostnames by hard coding them in a perl command on a test ESX server;
perl -e '$_ = "pdx-lab044.vmnet.local"; /^[a-z-A-Z]+([0-9]+)\.?.*/ ; printf "%d", $1'

One hundred templates with two commands
Let's break down the two one-liners we're going to use to create the templates. First, change directories into the UDA folder that stores the kickstart files:

cd /var/public/www/kickstart

Here's how the first one-line bash script will work:
  • First use seq to print the series of numbers 1 to 100 using a three digit format in a for loop

  • Then for each number, cat the master template into a sed filter

  • Use sed to replace the 00HOSTNAME00 tag with the specific hostname and number

  • And finally redirect each instance of the loop into a config file named with the sequence number

for i in `seq -f %03g 1 100`; do cat mastr.cfg | sed "s/00HOSTNAME00/pdx-lab$i/" > ./pd$i.cfg; \ 
chown apache:apache ./pd$i.cfg; done

There's a big gotcha here, remember that UDA insists you give each template a five character template ID, and we want all of our file names and template IDs to match up. In order for the file names from this command to end up being 5 characters long, we can only use two characters in front of the three digits generated from the seq command.

Now we need to update the templates.conf file to include all of the new kickstarts we just created. If you cat templates.conf, you'll notice that this is where the boot parameters for each template are kept. The boot parameters are visible in the UDA web console when you edit a template, in the text box just below the Save button. In our master template, the line is append ip=dhcp ksdevice=eth0 load_ramdisk=1 initrd=initrd.esx301 network ks=

The UDA templates.conf file has a unique line for each template with the boot parameters, and prepends a section in front with the unique name of the template, the OS for the template, and the Bind to MAC: address if you are using it:
We'll need to modify each new line as we add it to the file, changing mastr to the five character template ID we used when cloning the templates. Copy the boot parameters line from your master template in the UDA web console to use in the command below.

First we'll change directories into the /var/public/conf folder:

cd /var/public/conf

And back up templates.conf first just in case:

cp -p ./templates.conf ./backup_templates.conf

This is how the second one-line bash script will work:
  • Use seq again to print 1 to 100 using a three digit format in a for loop

  • Echo the boot parameters for each kickstart file, substituting the value of i each time

  • Append each unique line of the loop into the ./templates.conf file

for i in `seq -f %03g 1 100`; do echo \
"pd$i;esx301;configfilename;;00-00-00-00-00-00;append ip=dhcp ksdevice=eth0 \
load_ramdisk=1 initrd=initrd.esx301 network ks=$i.cfg" \
>> ./templates.conf; done

Right after you issue that command, if you click on Templates in the UDA web console, you should see all 100 of the new templates. Click Edit Configuration on one of them and check to make sure the hostname changed.

We're almost done, but if you boot up an unconfigured server hoping to use the new templates, you'll find that the TFTP boot menu doesn't have them.

The UDA wasn't meant to be used in this way, it only updates the boot menu when a template is added or removed. So all we need to do is create a dummy template, name it 12345, and just save it without configuring anything. Then go right back to Templates and delete it. That will rebuild the boot menu with all 100 options. You'll find the new TFTP boot menu scrolls all the way down the list to the last in the series of available templates, which is sort of lame, but it's not a big enough deal to try and figure out how the menu is created.

I messed up, how can I delete these without clicking 100 times in the UDA?!
If you backed up templates.conf with the command above before trying any of this out, just use mv with the -f (force) option to restore your original templates.conf file:

cd /var/public/conf
mv -f ./backup_templates.conf ./templates.conf

Now you can also delete all the template files, but first test the bulk delete with an ls command:

cd /var/public/www/kickstart
ls pd*.cfg

If ls gives you a list of the specific files you want to delete, then you can safely remove them with rm:

cd /var/public/www/kickstart
rm -f pd*.cfg

Disclaimer: Running these commands on your UDA virtual appliance could potentially spam it with thousands of bogus templates or ruin the template index file if you are not careful, so please back it up or take a snapshot before attempting this. The specific commands listed above were tested in the lab, but you are on your own when modifying the examples for use in your environment. Be careful and know what the commands are going to do before executing them!

Also, the creator of the UDA probably never meant for the appliance to be used in this way, so we should apologize and promise to never request assistance with this or complain if we ruin our UDAs with these commands. :-J

And finally, pay close attention to when backticks (`) are used as opposed to single quotes ('). I should be using the $( ) syntax for command substitution, but I just don't like the way it looks, I'm stuck on backticks.

# Create 100 templates, replacing 00HOSTNAME00 from a template 
# named /var/public/www/kickstart/mastr.cfg with pdx-labXXX
# and naming each new template pdXXX.cfg
for i in `seq -f %03g 1 100`; \
do cat /var/public/www/kickstart/mastr.cfg | sed "s/00HOSTNAME00/pdx-lab$i/" \
> /var/public/www/kickstart/pd$i.cfg; \
chown apache:apache /var/public/www/kickstart/pd$i.cfg; \

# Backup /var/public/conf/templates.conf, preserving ownership

cp -p /var/public/conf/templates.conf /var/public/conf/backup_templates.conf

# Add the 100 templates named pdXXX.cfg to the UDA template index 

for i in `seq -f %03g 1 100`; do echo \
"pd$i;esx301;configfilename;;00-00-00-00-00-00;append ip=dhcp ksdevice=eth0 \
load_ramdisk=1 initrd=initrd.esx301 network ks=$i.cfg" \
>> /var/public/conf/templates.conf; done

No comments:

Post a Comment