Building Virtual Appliances with OVF Properties and GuestInfo
I’m currently working on building virtual appliances that require configuration inputs during deployment.
There are several ways to create a virtual appliance (I’ll cover those methods in a future post). One simple and effective approach is:
- Create and configure a Virtual Machine
- Export it as an OVF/OVA using:
- The vSphere UI
- PowerCLI
- The vSphere API
In this post, I’ll focus on how to add deployment-time inputs (OVF properties) and how to reliably read them inside a Linux guest.
Adding Inputs to the OVF File
To allow the guest operating system to access deployment properties via guestinfo, you must modify the .ovf file.
Inside the VirtualHardwareSection, add the following attribute:
<VirtualHardwareSection ovf:transport="com.vmware.guestInfo">
Understanding OVA vs OVF
An OVA file is simply a packaged version of the OVF format.
.ovf→ XML descriptor file.vmdk→ Disk files.mf→ Manifest (checksum file).ova→ A single archive containing all of the above
Technically, an .ova is just a TAR archive (often described as similar to a zip file).
To modify it:
- Extract the OVA file
- Edit the
.ovffile - Update or remove the
.mffile
Important Note About the .mf File
The .mf file contains checksums for validation.
If you modify the .ovf, you must:
Delete the .mf file (this disables integrity validation — not recommended for production use)
- Recalculate and update the checksum in the
.mffile or - Delete the
.mffile (this disables integrity validation — not recommended for production use)
Adding OVF Deployment Properties
Deployment inputs are added inside a <ProductSection> in the OVF file.
Example:
<ProductSection ovf:required="true">
<Info>Information about the installed software</Info>
<Product>Allan Kjaer Virtual Appliance (AKVA)</Product>
<Vendor>Virtuel-Allan.com</Vendor>
<Version>v0.0.1</Version>
<ProductUrl>https://github.com/</ProductUrl>
<VendorUrl>https://www.virtual-allan.com/
<Category>Config</Category>
<Property ovf:key="akva.hostname" ovf:type="string" ovf:userConfigurable="true" >
<Label>Input hostname (FQDN)</Label>
<Description>Hostname for the Appliance</Description>
</Property>
<Property ovf:key="akva.function" ovf:type="string" ovf:userConfigurable="true" ovf:qualifiers="ValueMap{"1","2"}">
<Label>Appliance fuction</Label>
<Description>Function (1. Server, 2 Client)</Description>
</Property>
<Property ovf:key="akva.password" ovf:type="string" ovf:password="true" ovf:userConfigurable="true">
<Label>root Password</Label>
</Property>
<Property ovf:key="akva.debug" ovf:type="boolean" ovf:userConfigurable="true" ovf:value="false">
<Label>Use Debug looging</Label>
<Description>Enabling Debug logging will create a lot of log files</Description>
</Property>
</ProductSection>
Reading OVF Properties in Linux
There are some great blog posts about this topic, including one by William Lam:
However, there’s an important caveat.
The Problem: vCenter vs Standalone ESXi
The format of guestinfo.ovfEnv differs depending on how the appliance is deployed:
| Deployment Target | guestinfo Format |
|---|---|
| vCenter | Formatted XML |
| Standalone ESXi | Single-line XML |
William Lam’s example works well when deploying through vCenter, but when deploying directly to a standalone ESXi host, the returned XML is a single line. That breaks parsing logic that expects formatted XML.
A More Robust Script
Below is a script that works in both scenarios by explicitly formatting the XML before parsing it.
get-ova-property()
{
cat /tmp/guestinfoformatted.xml | grep $1 | awk '{print $3}' | sed -E 's/oe:value=\"//' | sed -E 's/\"\/>//'
}
read-ova-property()
{
while [ `/bin/guestinfosd --cmd 'info-get guestinfo.ovfEnv' > /tmp/guestinfo.xml 2>/tmp/guestinfo_err.log; echo $?` -ne 0 ]
do
sleep 30
if [ $retry -gt 1 ]
then
echo "guestinfosd not running properly" >> /tmp/guestinfo_err.log
break
else
retry=$(($retry+1))
fi
done
xmllint --format /tmp/guestinfo.xml > /tmp/guestinfoformatted.xml
}
read-ova-property
HOSTNAME=$(get-ova-property akva.hostname)
Final Thoughts
When building virtual appliances using OVF properties:
- Always enable
ovf:transport="com.vmware.guestInfo" - Be aware of deployment differences between vCenter and ESXi
- Handle XML formatting differences in your parsing scripts
- Maintain checksum integrity when modifying OVF files
This approach makes your appliance more flexible and production-ready across different deployment scenarios.