Most of us don’t like to install guest OS repeatedly, instead, we often install one guest OS, then do some setup and customization. After that, we make a backup of the disk image(We use it as a template). If we want to install the same OS later, we only need to copy that template disk image and create a new guest config file.
When create a new guest config file, we need to give it a unique name, a unique uuid, and a unique MAC address. Also, we need to change it’s disk file path. We can do this kind of changes manually, hower, according to the rule “automate all that can be automated”, we can use a script to do this.
Assume that we have a temaplate CentOS 5.6 guest, and here is its xml config file:
centos5.6.xml
<domain type='kvm'>
<name>centos56</name>
<uuid>f065c048-32a4-feb8-1702-78b8d828e450</uuid>
<memory>524288</memory>
<currentMemory>524288</currentMemory>
<vcpu>2</vcpu>
<os>
<type arch='x86_64' machine='rhel6.0.0'>hvm</type>
<boot dev='hd'/>
</os>
<features>
<acpi/>
<apic/>
<pae/>
</features>
<clock offset='utc'/>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<emulator>/usr/libexec/qemu-kvm</emulator>
<disk type='file' device='disk'>
<driver name='qemu' type='raw' cache='none'/>
<source file='/vmrepo/disk/centos5.6.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<interface type='bridge'>
<mac address='52:54:00:88:d0:51'/>
<source bridge='br1'/>
<model type='virtio'/>
</interface>
<serial type='pty'>
<target port='0'/>
</serial>
<console type='pty'>
<target port='0'/>
</console>
<memballoon model='virtio'>
</memballoon>
</devices>
</domain>
We can create a new guest VM from this template like this:
./newvm.py --name lvs --config ./centos5.6.xml #or this way: #./newvm.py -n lvs -c ./centos5.6.xml #both the -n and -c option are required.
This will create a file named lvs.xml under the current directory. Because making a copy of the template disk make take a long time, and sometimes we may use lvm as disk. so this script will not create the disk image for us. Instead, it outputs the disk path it will use:
Created vm config file lvs.xml Use disk image /vmrepo/disk/lvs.img, you must create it from the template disk: /vmrepo/disk/centos5.6.img Done!
Notes:
- The template xml config file may not include any pci addresses line, because different vm can not use the same PCI address, it will conflict
eg:<address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
lines like this must be removed from the template xml file.
- you need to install the python-virtinst package for uuid generation. On CentOS/RHEL 5.x, which uses python 2.4, you need to install the python-lxml package(this package is in epel repo.)
yum install python-virtinst yum install python-lxml #only on CentOS/RHEL 5.x
Here’s the script newvm.py
#!/usr/bin/python
# Used to create a vm from template
# By Curu Wong contact: prinbra(at)gmail(dot)com
import sys,os
from optparse import OptionParser
from virtinst.util import *
if sys.version_info < (2,5):
import lxml.etree as ET
else:
import xml.etree.ElementTree as ET
parser = OptionParser();
parser.add_option(“-n”, “–name”, dest=”name”,
help=”VM name”);
parser.add_option(“-c”, “–config”, dest=”config”,
help=”Template VM XML config file”);
(options, args) = parser.parse_args();
if not options.name or not options.config:
print “Usage %s -n name -c template_xml” % sys.argv[0]
sys.exit(1)
config = ET.parse(options.config)
vm_name = options.name
name = config.find(‘name’)
name.text = vm_name
uuid = config.find(‘uuid’)
uuid.text = uuidToString(randomUUID())
mac = config.find(‘devices/interface/mac’)
mac.attrib[‘address’] = randomMAC(type=’qemu’)
disk = config.find(‘devices/disk/source’)
disk_old = disk.attrib[‘file’]
disk_path = os.path.dirname(disk_old)
disk_ext = os.path.splitext(disk_old)[1]
disk_image = disk_path + ‘/’ + vm_name + disk_ext
disk.attrib[‘file’] = disk_image
if os.path.exists(vm_name + ‘.xml’):
print “File %s.xml exists, abort” % vm_name
sys.exit(1)
config.write(vm_name + ‘.xml’)
print “Created vm config file %s.xml” % vm_name
print “Use disk image %s, you must create it from the template disk: %s” % (disk_image, disk_old)
print “Done!”
[/Python]




Pingback: Linux KVM Maschinen manuell clonen | Thorsten's Blog
Pingback: Python Module for Creating new KVM XML Definitions from Templateall the layers
Pingback: Automated Virtualization and Host Deployment Part 4 – Setting Up Chefall the layers