kojivmd: Call out to virt-clone instead of virtinst

Reason is that virtinst is going away as a public library, hopefully
for F17. It wasn't ever really intended to be used publically, and it's
not very good :) Long term it will mostly go away anyways as we move to
libvirt-gobject based libraries.

Unfortunately this change doesn't simplify the koji code any, but it
should be equivalent functionality. I did some local unit testing to
verify it was giving sane results, but I'd appreciate if someone with
an actual koji setup could test.
This commit is contained in:
Cole Robinson 2012-02-14 15:10:29 -05:00 committed by Mike Bonnet
parent 479cf72be4
commit 1ced6e2b5e

View file

@ -34,7 +34,6 @@ import time
import subprocess
import libvirt
import libxml2
import virtinst
import random
import socket
import SimpleXMLRPCServer
@ -466,26 +465,56 @@ class VMExecTask(BaseTaskHandler):
VM. The original VM must be shutdown, or this will raise an error.
"""
clone_name = self.CLONE_PREFIX + str(self.id) + '-' + name
design = virtinst.CloneManager.CloneDesign(conn)
design.original_guest = name
design.clone_name = clone_name
design.setup_original()
orig_vm = conn.lookupByName(name)
orig_paths = self.guestDisks(orig_vm)
i = 0
for orig_disk in design.original_devices:
new_disk = self.mkqcow2(clone_name, orig_disk, i)
design.clone_devices = new_disk
i += 1
cmd = ["virt-clone", "--debug",
"--original", name, "--name", clone_name,
"--preserve-data"]
design.setup_clone()
# The CloneManager API doesn't always fix the type= of the <driver/> entry in
# the XML (if it exists), so do it manually.
for idx in range(len(orig_paths)):
orig_disk = orig_paths[idx]
new_disk = self.mkqcow2(clone_name, orig_disk, idx)
cmd += ["--file", new_disk]
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, close_fds=True)
ret = proc.wait()
if ret:
output = proc.stdout.read()
raise koji.BuildError('unable to clone VM: '
'"%s" returned %s; output was: %s' %
(' '.join(cmd), ret, output))
# The CloneManager API doesn't always fix the type= of the
# <driver/> entry in the XML (if it exists), so do it manually.
# Also set the cpus and mem parameters directly in the XML.
clone_xml = self.updateXML(design.clone_xml, opts)
newvm = conn.lookupByName(clone_name)
clone_xml = self.updateXML(newvm.XMLDesc(0), opts)
conn.defineXML(clone_xml)
return clone_name
def guestDisks(self, vm):
"""
Parse cloneable disks out of the original VM XML
"""
doc = libxml2.parseDoc(vm.XMLDesc(0))
ctx = doc.xpathNewContext()
ret = []
nodelist = ctx.xpathEval("/domain/devices/disk/source")
for node in nodelist:
for prop in node.properties:
if prop.name in ["file", "dev"]:
ret.append(node.prop(prop.name))
break
ctx.xpathFreeContext()
doc.freeDoc()
return ret
def macAddr(self, vm):
"""
Return the MAC address of the first network interface configured for the given VM.