Tuesday, June 25, 2013

Prompt-free Appliance deployment : the automation script

Fifth and last part of this series “Prompt-free Appliance deployment”. I’m sure, many of you didn’t understand why sending so much time and effort for such a small result.
It’s maybe right, but at least we learnt several interesting points regarding these Appliances, like :
* about the five disks and what they contain,
* for the VMWare users how to mount/umount one of the disks,
* where are all the scripts used for the VM configuration and what modifications are required to make them prompt-free
We can probably go even further in the analyzes, take only one or two disks out of the five (to make a VM for PIA only for instance), go further in the other script for other Peoplesoft components. But it would take even longer timer and effort. For those who are interesting in specific area, I hope that series offered a good start.

That said, there’s a very last effort. We previously modified the script manually, now it’s time for scripting. As a base start, I’ll reuse the previous script to move to ESXi.

1. Files involved
There are 3 files:
- 1 containing the sed replacement (replace.sed) – see explanations details in a previous post:
s/<OperatingSystemSection ovf:id="109">/<OperatingSystemSection ovf:id="101">/
s/<Description>Oracle_64<\/Description>/<Description>oracleLinux64Guest<\/Description>/
s/<vbox:OSType ovf:required="false">Oracle_64<\/vbox:OSType>/<vbox:OSType ovf:required="false">oracleLinux64Guest<\/vbox:OSType>/
s/<vssd:VirtualSystemType>virtualbox-2.2<\/vssd:VirtualSystemType>/<vssd:VirtualSystemType>vmx-07<\/vssd:VirtualSystemType>/
s/<rasd:Caption>sataController0<\/rasd:Caption>/<rasd:Caption>SCSI Controller0<\/rasd:Caption>/
s/<rasd:Description>SATA Controller<\/rasd:Description>/<rasd:Description>SCSI Controller<\/rasd:Description>/
s/<rasd:ElementName>sataController0<\/rasd:ElementName>/<rasd:ElementName>SCSI Controller0<\/rasd:ElementName>/
s/<rasd:ResourceSubType>AHCI<\/rasd:ResourceSubType>/<rasd:ResourceSubType>lsilogic<\/rasd:ResourceSubType>/
s/<rasd:ResourceType>20<\/rasd:ResourceType>/<rasd:ResourceType>6<\/rasd:ResourceType>/

- 1 containing the configuration settings.
This file is the only file to be modify when creating a new VM according to the expectations:
[root@omsa:/nfs/software/PeopleSoftCD/OVA]# more HCMDB-SES-85302d.env
#Please change the value as desired
ROOT_PWD="passw0rd"
IP_ADDRESS="192.168.1.20"
NETMASK="255.255.255.0"
GATEWAY="192.168.1.254"
DNS="192.168.2.254"
HOST_NAME="hcm92000.phoenix.nga"
DB_NAME="HR92DMO"
SES_Y_N="N"
VMWARE_ANNOTATIONS="Peoplesoft Appliance PUM HCMDB Peoplesoft 9.2 Peopletools 8.53.02 - Demo use"
VMWARE_TOOLS_ISO_PATH="/nfs/software/Virtualization/VMWare/VMWare_vSphere/5.1u1"
VMWARE_TOOLS_ISO_FILE="VMware-tools-linux-9.0.5-1065307.iso"
[root@omsa:/nfs/software/PeopleSoftCD/OVA]#

- 1 being the shell script itself, see next section.

2. The shell script
The first part is easy to understand, you must provide a configuration file as shown above
[root@omsa:/nfs/software/PeopleSoftCD/OVA]# more ova_to_esx.sh
if [ "$1" = "" ];
then
echo "You must specify a file as input parameter"
exit 1
else
ENV=$1
if [ -f ${ENV} ];
then
. ./${ENV}
else
echo ${ENV}" does not exists or is not a file"
exit 1
fi
fi

Then fill up the name of the input virtual machine as well as the output
inputVM=""
while [ "$inputVM" = "" ];
do
echo "Please enter input name (corresponding to the folder with zip/ova/ovf):"
read inputVM
if [ ! -d ${inputVM} ];
then
echo "The directory ./${inputVM} does not exist"
inputVM=""
fi
done

echo "Please enter the output VM name (default=${inputVM}): "
read outputVM
if [ "${outputVM}" = "" ];
then
outputVM=${inputVM}
fi

There is a confirmation prompt:
echo "########################################"
echo "#  Input parameters"
echo "########################################"
echo "inputVM ...............: "${inputVM}
echo "outputVM ..............: "${outputVM}
echo "Root password .........: "${ROOT_PWD}
echo "IP address ............: "${IP_ADDRESS}
echo "Netmask ...............: "${NETMASK}
echo "Gateway ...............: "${GATEWAY}
echo "DNS ...................: "${DNS}
echo "Hostname ..............: "${HOST_NAME}
echo "Database name .........: "${DB_NAME}
echo "SES installation ......: "${SES_Y_N}
echo "VMWare annotations ....: "${VMWARE_ANNOTATIONS}
echo "VMWare iso ............: "${VMWARE_TOOLS_ISO_PATH}"/"${VMWARE_TOOLS_ISO_FILE}
echo "########################################"
PROCEED=""
while [ "${PROCEED}" != "Y" -a "${PROCEED}" != "N" ];
do
echo "Do you want to proceed with these values (y=continue, n=exit)?"
read PROCEED
PROCEED=`echo "${PROCEED^^}"`
done
if [ ${PROCEED} = "N" ];
then
echo "You choose not to proceed, exit script."
exit 1
fi
echo "Continue the script..."

And all the following is running automatically, starting by unzipping, concatenate, extract ova file, update ovf file, and push to ESXi (ovftool):
##############################################################################################
cd ${inputVM}
echo $PWD

##############################################################################################
echo `date`
echo "Start"
#Unzip the input zipfiles
echo "Unzipping input files"
for zipfile in `ls ${inputVM}*.zip`
do
echo `date`
echo "unzipping file "$zipfile
unzip $zipfile
done

##############################################################################################
#Concatenation to one ova file
echo "Concatenation to one ova file"
if [ -f ${inputVM}.ova ];
then
rm -f ${inputVM}.ova
fi

for ovafile in `ls ${inputVM}.ova_?of?`
do
echo `date`
echo "concatenation file "$ovafile
cat $ovafile >> ${inputVM}.ova
done

##############################################################################################
#Extract files from ova
echo `date`
echo "Extract ova file"
if [ -f ${inputVM}.ova ];
then
echo "untar the ova file"
tar xvf ${inputVM}.ova
fi

##############################################################################################
#Backup the ovf
mv ${inputVM}.ovf ${inputVM}.ovf.orig

##############################################################################################
#Replace the string to be replace as defined in replace.sed file
echo "Change the ovf to ESXi compliance"
sed -f ../ova_to_esx.sed < ${inputVM}.ovf.orig > ${inputVM}.tmp

#Take the item line corresponding to the sound item group
line=`grep -ni -B7 sound ${inputVM}.tmp|grep  "<Item>"|awk -F- '{print $1}'`
#It will replace the <Item> for the sound card item to be deactivated
sed -e "${line}s/<Item>/<Item ovf:required=\"false\">/" < ${inputVM}.tmp > ${inputVM}.ovf
rm -f ${inputVM}.tmp

##############################################################################################
echo `date`
echo "Moving to ESXi"
##############################################################################################
#ovftool --lax -ds=vm "--net:HostOnly=VM Network 2" ${inputVM}.ovf "vi://root:pwd@192.168.1.10:443"
#Creation of the local ovftool parameter file
echo "lax" > .ovftool
echo "datastore=vm" >> .ovftool
echo "skipManifestCheck" >> .ovftool
echo "overwrite" >> .ovftool
echo "powerOffTarget" >> .ovftool
echo "net:HostOnly=VM Network 2" >> .ovftool
#echo "powerOn" >> .ovftool
echo "annotation="${VMWARE_ANNOTATIONS} >> .ovftool
echo "name="${outputVM} >> .ovftool

echo $PWD
#Run the ovftool to push the ovf and vmdk to ESXi
ovftool ${inputVM}.ovf vi://root:pwd@192.168.1.10:443

#Remove local ovftool parameter file
rm -f .ovftool

Then it’s taking back the 1st disk from the remote ESXi to the local machine:
##############################################################################################
echo "Loading the vmdk from ESXi "`date`
##############################################################################################

##Taking back the 1st vmfk
mkdir -p ${outputVM}-esxi
vifs --server 192.168.1.10:443 --username root --password pwd --get '[vm] '${outputVM}'/'${outputVM}'-flat.vmdk' ./${outputVM}-esxi
echo `date`

Mounting and updating all the needed scripts:
##############################################################################################
echo "Mounting the loaded vmdk from ESXi "`date`
##############################################################################################
#Mounting the downloaded vmdk on local
lo1=`losetup --find`
echo "Loop free "${lo1}
losetup ${lo1} ./${outputVM}-esxi/${outputVM}-flat.vmdk
start=`fdisk -lu ${lo1}|grep Linux|grep -v "*"|grep -v swap|awk '{print $2}'`
echo "Start offset "${start}
offset=`expr ${start} \\* 512`
echo "Size offset "${offset}
lo2=`losetup --find`
echo "Loop free "${lo2}
losetup ${lo2}  ${lo1} -o ${offset}
echo "Mounting fs..."
mkdir -p /mnt/${outputVM}
mount  ${lo2} /mnt/${outputVM} -o rw,user

##############################################################################################
echo "Backing up scripts"
#####################
#Backing up scripts
#####################
cp /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh.orig
cp /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh.orig
#####################

echo "Banner"
#####################
#Banner
#####################
mv /mnt/${outputVM}/opt/oracle/psft/vm/.banner /mnt/${outputVM}/opt/oracle/psft/vm/.banner.orig
#####################

echo "Database"
#####################
#Database
#####################
sed -i "s/.*Enter the name of the database.*//"  /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh
sed -i "s/read VALUE/VALUE=\"${DB_NAME}\"/" /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh

echo "Root password"
#####################
#Root password
#####################
sed -i "/.*ovm_configure_network.*/a\
sed -i \"s\/ovm_set_password.*\/ovm_set_password root "${ROOT_PWD}"\/\" \$ORACLE_DB_SCRIPT" /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh

echo "Network"
#####################
#Network
#####################
sed -i "s/.*ovm_configure_network.*/sed -i \"s\/ovm_configure_network.*\/ovm_configure_network "${IP_ADDRESS}" "${NETMASK}" "${GATEWAY}" "${DNS}" "${HOST_NAME}"\/
\" \$ORACLE_DB_SCRIPT/"  /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template-db.sh

echo "SES"
#####################
#SES
#####################
if [ ${SES_Y_N} = "Y" ]; then
sed -n '1h;1!H;${;g;s/echo -n \"Do you wish to setup Secure Search Enterprise.*USER_RESPONSE=\"\$?\"/USER_RESPONSE=1/g;p;}' < /mnt/${outputVM}/opt/oracle/psft/vm/
oraclevm-template.sh > /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh.out
else
sed -n '1h;1!H;${;g;s/echo -n \"Do you wish to setup Secure Search Enterprise.*USER_RESPONSE=\"\$?\"/USER_RESPONSE=0/g;p;}' < /mnt/${outputVM}/opt/oracle/psft/vm/
oraclevm-template.sh > /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh.out
fi
rm -f  /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh
mv /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh.out  /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh
chmod a+rx  /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh

Making all the stuff for VMWare tools:
echo "VMWare tools"
#####################
#VMWare tools script, run only the first time
#####################
echo "if [ -f /tmp/"${VMWARE_TOOLS_ISO_FILE}" ]; then" > /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "mkdir -p /mnt/vmware-tools" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "mount -o loop /tmp/"${VMWARE_TOOLS_ISO_FILE}" /mnt/vmware-tools" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "tar zxf /mnt/vmware-tools/VMwareTools*.tar.gz -C /tmp" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "umount /mnt/vmware-tools" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "rmdir /mnt/vmware-tools" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "rm -f /tmp/${VMWARE_TOOLS_ISO_FILE}" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "/tmp/vmware-tools-distrib/vmware-install.pl --default" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "rm -Rf /tmp/vmware-tools-distrib" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
echo "fi" >> /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
#
chmod a+rx /mnt/${outputVM}/opt/oracle/psft/vm/vmware_tools.sh
#
sed -i "/CreateVirtualEnv$/a\
\$SCRIPT_PATH\/vmware_tools.sh" /mnt/${outputVM}/opt/oracle/psft/vm/oraclevm-template.sh
#####################
echo "Copy VMWare tools installer "`date`
#Copy the iso VMWare tools installer
cp ${VMWARE_TOOLS_ISO_PATH}"/"${VMWARE_TOOLS_ISO_FILE} /mnt/${outputVM}/tmp
##############################################################################################

Two more optional steps to fix previously found issues (you may add more):
#####################
#Optional: disabling SELINUX in /etc/selinux/config if empty
#####################
echo "Disabling SELINUX"
sed -i "s/^SELINUX=$/SELINUX=disabled/" /mnt/${outputVM}/etc/selinux/config

#####################
#Optional: smb configuration settings
#####################
echo "SMB netbios configuration"
cp /mnt/${outputVM}/etc/samba/smb.conf /mnt/${outputVM}/etc/samba/smb.conf.bkp
sed -i "s/netbios.*/netbios name = "${outputVM}"/" /mnt/${outputVM}/etc/samba/smb.conf

Once all the modifications are done, unmount everything and put back the 1st disk from local to remote ESXi:
##############################################################################################
echo "Dismounted all "`date`
echo "Umounting fs..."
##############################################################################################
umount /mnt/${outputVM}
echo "Freed loops..."
losetup -d ${lo2}
losetup -d ${lo1}
rmdir /mnt/${outputVM}

##############################################################################################
echo "Putting back the vmdk to ESXi "`date`
##############################################################################################
vifs --server 192.168.1.10:443 --username root --password pwd --put ./${outputVM}-esxi/${outputVM}-flat.vmdk '[vm] '${outputVM}'/'${outputVM}'-flat.vmdk'
rm -Rf ./${outputVM}-esxi

Eventually it’s starting up the new virtual machine and install the VMWare tools:
##############################################################################################
echo "Starting up the virtual machine..."
##############################################################################################
#Taking the ID of the new VM
VMID=`ssh 192.168.1.10 <<EOF
/bin/vim-cmd vmsvc/getallvms |grep " "${outputVM}" "
EOF`
VMID=`echo $VMID|awk '{print $1}'`
echo "ID virtual machine "${VMID}
#Taking the status of the new VM
VM_OFF=`ssh 192.168.1.10 <<EOF
/bin/vim-cmd vmsvc/power.getstate ${VMID}|grep "Powered off"|wc -l
EOF`
#Starting the new VM
if [ ${VM_OFF} -eq 0 ]; then
echo "The virtual machine ${outputVM} is already started"
else
ssh 192.168.1.10 <<EOF
/bin/vim-cmd vmsvc/power.on ${VMID}
EOF
fi
##############################################################################################
#If the VMWare tools are installed, then the VM is ready because it is the very last step of first VM starting up
##############################################################################################
echo "Waiting for initialization... Please be patient"
TOOLS=0
while [ ${TOOLS} -eq 0 ];
do
TOOLS=`ssh 192.168.1.10 <<EOF
grep toolbox: /vmfs/volumes/vm/${outputVM}/vmware.log|wc -l
EOF`
if [ ${TOOLS} -eq 0 ]; then
echo "Waiting for 60 seconds..."
sleep 60
fi
done
##############################################################################################
echo "The VM ${outputVM} is ready to use"
##############################################################################################
echo "End"`date`
cd -
[root@omsa:/nfs/software/PeopleSoftCD/OVA]#

It is ending the series on People Appliance prompt-free deployment.

Not sure if that script will be useful for many people and if it will work with the upcoming Demo Appliances, but what we can retain from this series:
* We heavily used “sed” command, it’s always good to manipulate.
* We came across mount disk issue and losetup command, it’s rather worth for Linux administrator.
* We use several interesting VMWare tool (ovftool) and VMWare client or host command lines (like the one to get/put file from/to ESXi, or start the VM).
* And also, we went through the configuration and settings of the virtual machines themselves (disks description, scripts used for deployment…).

So, whether it is really useful or not does not really matter, since it covered a wide scope of knowledge and tools, I hope many people learnt a piece of code which is out of their interest.

Nicolas.

Ref:
Password free access to ESXi host:
http://blogs.vmware.com/vsphere/2012/07/enabling-password-free-ssh-access-on-esxi-50.html
Starting a VM from command line:
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1038043
Check VMWare tools installed:
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1003947

No comments: