Motivation
I had a hard time creating a RedHat template that actually behaves
the way I was expecting. My current template does this and I
would like to share my setup with a larger audience. Hopefully
somebody has some alternatives which require a little less
"tweaking".
Basic Configuration
A VMware host running ESXi 4.0.0 (171294), the vSphere
Server/Client are V4.0.0 (208111).
Requirements
Create some 50+ RedHat Enterprise Linux systems (V5.5) with Oracle
V11 and a few other software packages installed (like
CommVault/Simpana backup). Our environment requires static IP
addresses.
General Procedure
The idea is to create a template, which has all the necessary
components installed. During deployment, only the system name,
its IP address and the root password have to be specified.
Details
create a VM which will later be used as a template
create a VM with apropriate resources (memory, disk, etc.)
install RHEL 5.5, apply all patches
install other software products
the configuration of software products requires attention - any customization/configuration that is system specific has to be done (or re-done) at deployment time
create a "customization specification"
set OS to Linux, specify name of this "guest customization specification"
set "use the virtual name" as computer name, specify domain
set time zone, set HW clock to localtime
choose "custom settings" for network
check "prompt user for IP address", set mask and default gateway
provide DNS addresses, set search domain
finish the "customization specification"
convert VM to template
The general idea is to shutdown the
VM, convert it into a template and then deploy new VMs from this
template using the above “customization specification”. The name
of such a new VM would be used as its hostname and the user is
prompted for a new IP address during this deployment process.
Unfortunately, it's not quite that easy.
When such a VM boots the first time,
it still has the “old” configuration, i.e., networking starts
with the IP address of the template VM and the logging facility start
with the hostname of the template. It appears, that the startup
scripts for VMware (/etc/init.d/vmware-tools) pulls in the new values
for hostname and IP address, but they don't get activated.
To prevent this, I modify the script
“/etc/init.d/firstboot”. This script is normally executed only
during the first boot of the system after the installation of the OS.
If it is set to run, it is started rather late during the startup
process, long after “vmware-tools” has been executed and the new
hostname and IP address is available. In this script I added three
instructions. One is to remove the “/etc/localtime” file. This
is only done to prevent error messages when “firstboot” is trying
to set the timezone (these error messages can be ignored, but I don't
want to confuse the user with error messages). The other two
instructions are a) restart the network to pick up the new IP address
and b) restart the logging facility to pick up the new hostname. The
modifications are listed below.
The only thing that remains to do is
to ensure that “firstboot” is executed during the first boot of a
VM created from the template. This is done by either deleting the
file “/etc/sysconfig/firstboot”, or by replacing the line
“RUN_FIRSTBOOT=NO” with “RUN_FIRSTBOOT=YES”. In addition,
firstboot knows the “--reconfigure” option, which will cause
“firstboot” to ask for a new root password. This option is
triggered by the existence of the file “/etc/reconfigSys”. When
“firstboot” runs, it deletes the file “/etc/reconfigSys” and
it creates the file “/etc/sysconfig/firstboot” with the single
line “RUN_FIRSTBOOT=NO”. This prevents “firstboot” from
running again ever.
To prepare the VM for “converting
into a template”, I created a script which deletes
“/etc/sysconfig/firstboot”, creates “/etc/reconfigSys” and
the shuts down the VM. The shutdown is using “-F” option to
enforce a file system check at next boot. This is not strictly
necessary, but it puts “some” users at ease when they see that
the filesystems are okay after they had been copied from the
template.
So, now my procedure to convert the
VM to a template looks like this:
modify “/etc/init.d/firstboot” as explained above (see listing below)
create “/root/bin/PrepareTemplate.sh” as explained above (see listing below)
run the script “/root/bin/PrepareTemplate.sh”
wait until the shutdown is complete
convert VM into template using vSphere
deploy from template
When a new VM based on this template
has to be created, I follow these steps:
“deploy virtual machine from this template” in vSphere
the name of the new VM will also be assigned as its hostname
in the dialog “Guest Customization” select “Customize using an existing customization specification” and select the previously created customization specification
provide the IP address of the new VM
boot into the VM using the VM Console and follow dialog
once the new VM is up and running, some of the additional software packages need some attention, e.g., I have to register the system with the backup server, etc.
Script “/etc/init.d/firstboot”:
#!/bin/bash
#
#
firstboot: Starts the firstboot druid if it hasn't been run
before
#
#
chkconfig: 35 99 95
#
#
description: Firstboot is a druid style program that runs on
the first time \
#
a machine is booted after install. It checks for
the existence \
#
of an /etc/sysconfig/firstboot file. If it
doesn't find the file, \
#
then the firstboot program needs to run. If it
finds the file, \
#
firstboot will not be run.
#
If /etc/reconfigSys exists, run the
reconfiguration
#
program and remove /etc/reconfigSys when done.
#
#
Also will run if 'reconfig' is on the kernel
cmdline.
#
#
Source function library.
.
/etc/init.d/functions
FILENAME=/etc/sysconfig/firstboot
LOCKFILE=/var/lock/subsys/firstboot
[
-z "$HOME" ] && export HOME=/
case
"$1" in
start)
action=run
[
-f "$LOCKFILE" ] && exit 0
if
&& ! grep -q
'^RUN_FIRSTBOOT=YES' "$FILENAME"; then
action=skip
fi
if
grep -i reconfig /proc/cmdline >/dev/null || [ -f /etc/reconfigSys
]; then
action=reconfig
fi
[
$action = skip ] && exit 0
runlevel=$(set
-- $(runlevel); eval "echo \$$#" )
if
grep -q "^id:5:initdefault:" /etc/inittab && [
"x$runlevel" = x5 ]; then
. /etc/sysconfig/i18n
if http:// ! -f /etc/X11/xorg.conf -a ! -f /etc/X11/XF86Config ; then
echo
-n $"X is not configured. Running system-config-display"
/usr/bin/system-config-display
echo
-n $"X is now configured. Starting Setup Agent"
fi
fi
if
; then
echo -n $"Running system reconfiguration tool"
rm -f /etc/localtime # wkuballa: prevent two error dialogs
/usr/sbin/firstboot --reconfig
/etc/init.d/network restart # wkuballa: use new IP Address
/etc/init.d/syslog restart # wkuballa: change host name in log
file
exit 0
fi
touch
$LOCKFILE
/usr/sbin/firstboot
RETVAL=$?
if
; then
action "" /bin/true
else
action "" /bin/false
fi
exit
0
;;
stop)
rm
-f $LOCKFILE
;;
*)
echo
$"Usage: $0 {start|stop}"
RETVAL=1
esac
exit
$RETVAL
Script “/root/bin/PrepareTemplate.sh”:
#!/bin/bash
#
This script prepares a VM to be used as a template.
#
#
After executing this script, the VM should be converted
#
into a template. New VMs deployed using this template
#
will execute RedHat's "firstboot" script, which is setting
#
hostname, IP addresses, etc. The new VM will also run
#
a filesystem check to ensure that the new virtual disk
#
has been created without problems.
#
prepared by Werner Kuballa, 9-Aug-2010
Host="$(hostname)"
case
"$Host" in
RHEL55small)
isAllowed=true;;
wkuballa-tst-*)
isAllowed=true;;
*)
isAllowed=false;;
esac
if
! $isAllowed; then
read
-p "this host is not a known template host - continue anyway?
(y/n) " Reply
[
"$Reply" == "y" ] && isAllowed=true
fi
if
$isAllowed; then
read
-p "enforcing \"system reconfiguration\" at next
reboot and shutting down - continue? (y/n) " Reply
[
"$Reply" != "y" ] && isAllowed=false
fi
if
! $isAllowed; then
echo
"aborting...."
exit
1
fi
#
force "firstboot" at next boot
cat
>/etc/sysconfig/firstboot <<-EOM
RUN_FIRSTBOOT=YES
EOM
#
force usage of "firstboot" with "--reconfigure"
option
touch
/etc/reconfigSys
#
force a filesystem check at next reboot
echo
"all preparations performed, shutting down in one minute ....."
shutdown
-h -F +1
exit
0