Friday 6 July 2012

Tweak your libvirt XML with XSLT

I wanted to clone a KVM VM, and while there a several tools to do the job, I fancied doing it 'the hard way'.

Plan

  1. Get the libvirt XML definition for the XML
  2. Tweak it with an XSLT stylesheet
  3. Put it back in for the new VM
Then I can clone the HD, mount it, change some of the bits in there and voila - new VM.

Implementation

You need 'xsltproc' to perform the XSLT transformation from the commandline - easy on Ubuntu:
# apt-get -y install xsltproc
Here's the XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- tweak libvirt XML file when cloning simple VM --> <!-- xsltproc --stringparam newUUID 1234-5678-90zbcdef --stringparam newMAC 11:22:33:44:55:66            --stringparam newNAME fred clone.xsl eg.xml                            --> <xsl:output omit-xml-declaration="yes" />
 <xsl:param name="newUUID" select="'XXX-YYY-ZZZ'"/> <xsl:param name="newMAC" select="'XX:YY:ZZ:XX:YY:ZZ'"/> <xsl:param name="newNAME" select="'XYZ'"/> <xsl:param name="newMEMORY" select="'1048575'"/> <xsl:param name="newROOT" select="'/XYZ/ROOT.qcow'"/>
 <xsl:template match="node()|@*">  <xsl:copy>   <xsl:apply-templates select="node()|@*"/>  </xsl:copy> </xsl:template>
 <xsl:template match="uuid/text()">  <xsl:value-of select="$newUUID"/> </xsl:template>
 <xsl:template match="imagelabel/text()|label/text()">  <xsl:text>libvirt-</xsl:text><xsl:value-of select="$newUUID"/> </xsl:template>
 <xsl:template match="mac/@address">  <xsl:attribute name="address">   <xsl:value-of select="$newMAC"/>  </xsl:attribute> </xsl:template>
 <xsl:template match="memory/text()|currentMemory/text()">  <xsl:value-of select="$newMEMORY"/> </xsl:template>
 <xsl:template match="/domain/name/text()">  <xsl:value-of select="$newNAME"/> </xsl:template>
 <xsl:template match="disk/source/@file">  <xsl:attribute name="file">   <xsl:value-of select="$newROOT"/>  </xsl:attribute> </xsl:template>
</xsl:stylesheet>
Just needs the parameters specifying to override the sample ones in the scripts when you invoke it...

$ xsltproc --stringparam newNAME testvm --stringparam newMAC 11:22:33:44:55:66 clone.xsl oldvm.xml
And the new XML comes out on stdout.