Before converting a running virtual machine to an OVA (redistributable virtual appliance), what does one need to do to ensure it is in a ready state so the instances of the OVA don't bring along unnecessary or potentially disruptive cruft from the build process? This is what I have so far. Am I missing anything? If this has already been answer or there is a Best Common Practices document, I'd appreciate a pointer in the right direction. Thanks.
################################# ## ## Get all packages up2date and ## clean out any cruft in the ## local packages ## ################################# yum -y update ; yum clean all ; ################################# ## ## Get rid of the signs I was ## tinkering with this ## ################################# [[ -a /etc/issue-original,v ]] && unlink /etc/issue-original,v ; [[ -a /etc/issue,v ]] && unlink /etc/issue,v ; ci -u /etc/issue ; ################################# ## ## Remove the host-keys to they ## will be regenerated when the ## new VM is spun-up ## ## Also make sure I remove any ## personal keys I may have been ## using while setting up ## ################################# find /etc/ssh/*host* |xargs unlink ; find /root/.ssh/ -type f |xargs unlink ; find /home/*/.ssh/ -type f |xargs unlink ; ################################# ## ## Get rid of the use of UUID in ## FSTAB and any NIC configuration ## so the new VM can find then when ## the UUIDs are regenerated ## ## Since we use LVM, only the /boot ## slice is a direct slice reference ## the rest are logical volumes ## ################################# sed -i -e 's/UUID=[0-9a-f-]*\s/\/dev\/sda1\t/' /etc/fstab ; sed -i -e '/^UUID=[0-9a-f-]*.*/d' /etc/sysconfig/network-scripts/ifcfg-eno* ; sed -i -e '/^UUID=[0-9A-F-]*.*/d' /etc/sysconfig/network-scripts/ifcfg-eno* ; find /etc/udev/rules.d/ -iname '70*net*' |xargs unlink ; ################################# ## ## Let the NTP daemon know to ## expect a big jump in time, so ## he doesn't freak out. Also let ## him know that if the walls melt, ## it is the acid, speaking and ## he'll be alright ## ################################# [[ -a /etc/ntp.conf ]] && \ [[ "$(head -1 /etc/ntp.conf)" == "tinker panic 0" ]] || \ sed -i -e '1itinker panic 0\n' /etc/ntp.conf ; ################################# ## ## Trunate the command-histories ## because the learning-process ## can contain some embarrassing ## mistakes, some of which are ## also bad opsec ## ################################# >/root/.bash_history ; >/home/*/.bash_history ; >/root/anaconda-ks.cfg ; ################################# ## ## Lastly, instruct the OS to redo ## the initial setup and put back ## that new-machine-smell ## ################################# sys-unconfig ;
I don't have access to our current cleanup script right now, but one of things we take into account is the appliance can maybe be deployed without running the proper customization steps. That means, for instance, the hostname on the original image might live on, and has to be reset before closing. We usually set ours to
localhost
.With that in mind, these are extra steps you might need to take care of
/etc/hosts
,/etc/resolv.conf
,/etc/sysconfig/network
of any customized values/etc/sysconfig/network-scripts/route-eno*
), if you have themcat /dev/null > /var/log/wtmp
), so they start up empty/var/tmp
and/tmp
/var/log/vmware-imc/*
)/etc/sysconfig/rhn
or similar back to default values. From experience,rm
'ing these is a bad idea. We usually just make a backup when first creating the image, and mv that back when closing it down. Same goes for/etc/sysconfig/osad
, if your environment uses it.Last, but not least, you can zero out every single filesystem plus the extra unused VG space, so you can better compress the image. We have a script that goes into every filesystem, dd's a bunch of zeroes until it fills up, then removes the file. Same for a VG with empty space, create an LV that fills 100%FREE, zero it out and remove it. After finishing these last steps (the last ones before powering down), you can use a trick depending on the kind of image you're creating:
qemu-img convert -f raw -O qcow2 -c source.raw destination.qcow2
One thing we've taken from this process is, every time we run thru a new cycle of images, we learn of something new we could've added, usually only after it has shipped. This gets added to the next cycle, and so on.
EDIT: on the spirit of the "every time we learn something new", the following steps were added last time: