mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-02-10 07:25:51 -06:00
XMLBuilder: Drop some is_parse checking
This commit is contained in:
parent
2ba3ec2684
commit
e0190f7b5e
@ -33,8 +33,8 @@ from virtinst import util
|
||||
from virtinst import support
|
||||
from virtinst.osxml import OSXML
|
||||
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
|
||||
from virtinst.VirtualDevice import VirtualDevice
|
||||
from virtinst.VirtualDisk import VirtualDisk
|
||||
from virtinst.VirtualDevice import VirtualDevice
|
||||
from virtinst.Clock import Clock
|
||||
from virtinst.Seclabel import Seclabel
|
||||
from virtinst.CPU import CPU
|
||||
@ -191,19 +191,18 @@ class Guest(XMLBuilder):
|
||||
self.domain = None
|
||||
self._consolechild = None
|
||||
|
||||
# Since we overwrite _parsexml handling, need to set up some
|
||||
# internal state before calling __init__
|
||||
XMLBuilder.__init__(self, conn, parsexml)
|
||||
if self._is_parse():
|
||||
return
|
||||
|
||||
self.installer = virtinst.DistroInstaller(conn)
|
||||
|
||||
# Need to do this after all parameter init
|
||||
self.os = OSXML(self.conn, parsexml, parsexmlnode)
|
||||
self.features = DomainFeatures(self.conn)
|
||||
self.clock = Clock(self.conn)
|
||||
self.seclabel = Seclabel(self.conn)
|
||||
self.cpu = CPU(self.conn)
|
||||
self.numatune = DomainNumatune(self.conn)
|
||||
self.os = OSXML(self.conn, None, self._xml_node)
|
||||
self.features = DomainFeatures(self.conn, None, self._xml_node)
|
||||
self.clock = Clock(self.conn, None, self._xml_node)
|
||||
self.seclabel = Seclabel(self.conn, None, self._xml_node)
|
||||
self.cpu = CPU(self.conn, None, self._xml_node)
|
||||
self.numatune = DomainNumatune(self.conn, None, self._xml_node)
|
||||
|
||||
|
||||
######################
|
||||
@ -340,16 +339,13 @@ class Guest(XMLBuilder):
|
||||
@param dev: VirtualDevice instance to attach to guest
|
||||
@param set_defaults: Whether to set defaults for the device
|
||||
"""
|
||||
if not isinstance(dev, VirtualDevice):
|
||||
raise ValueError(_("Must pass a VirtualDevice instance."))
|
||||
|
||||
if self._is_parse():
|
||||
xml = dev.get_xml_config()
|
||||
node = libxml2.parseDoc(xml).children
|
||||
dev.set_xml_node(node)
|
||||
self._add_child_node("./devices", node)
|
||||
self._add_child("./devices", dev)
|
||||
|
||||
self._track_device(dev)
|
||||
if self._is_parse():
|
||||
self._recalculate_device_xpaths()
|
||||
|
||||
if set_defaults:
|
||||
origdev = self._devices
|
||||
try:
|
||||
@ -358,10 +354,10 @@ class Guest(XMLBuilder):
|
||||
except:
|
||||
self._devices = origdev
|
||||
|
||||
|
||||
def _track_device(self, dev):
|
||||
self._devices.append(dev)
|
||||
|
||||
|
||||
def get_devices(self, devtype):
|
||||
"""
|
||||
Return a list of devices of type 'devtype' that will installed on
|
||||
@ -403,9 +399,10 @@ class Guest(XMLBuilder):
|
||||
raise ValueError(_("Did not find device %s") % str(dev))
|
||||
|
||||
if self._is_parse():
|
||||
xpath = dev.get_xml_node_path()
|
||||
xpath = dev.get_root_xpath()
|
||||
if xpath:
|
||||
self._remove_child_xpath(xpath)
|
||||
self._recalculate_device_xpaths()
|
||||
|
||||
|
||||
################################
|
||||
@ -415,51 +412,32 @@ class Guest(XMLBuilder):
|
||||
def _parsexml(self, xml, node):
|
||||
XMLBuilder._parsexml(self, xml, node)
|
||||
|
||||
device_mappings = {
|
||||
"disk" : virtinst.VirtualDisk,
|
||||
"interface" : virtinst.VirtualNetworkInterface,
|
||||
"sound" : virtinst.VirtualAudio,
|
||||
"hostdev" : virtinst.VirtualHostDevice,
|
||||
"input" : virtinst.VirtualInputDevice,
|
||||
"serial" : virtinst.VirtualSerialDevice,
|
||||
"parallel" : virtinst.VirtualParallelDevice,
|
||||
"console" : virtinst.VirtualConsoleDevice,
|
||||
"channel" : virtinst.VirtualChannelDevice,
|
||||
"graphics" : virtinst.VirtualGraphics,
|
||||
"video" : virtinst.VirtualVideoDevice,
|
||||
"watchdog" : virtinst.VirtualWatchdog,
|
||||
"controller": virtinst.VirtualController,
|
||||
"filesystem": virtinst.VirtualFilesystem,
|
||||
"smartcard" : virtinst.VirtualSmartCardDevice,
|
||||
"redirdev" : virtinst.VirtualRedirDevice,
|
||||
"memballoon": virtinst.VirtualMemballoon,
|
||||
"tpm" : virtinst.VirtualTPMDevice,
|
||||
}
|
||||
|
||||
# Hand off all child element parsing to relevant classes
|
||||
for node in self._xml_node.children:
|
||||
if node.name != "devices":
|
||||
continue
|
||||
|
||||
children = [x for x in node.children if
|
||||
(x.name in device_mappings and
|
||||
x.parent == node)]
|
||||
for devnode in children:
|
||||
devnode.virtinst_root_doc = self._xml_root_doc
|
||||
objclass = device_mappings.get(devnode.name)
|
||||
|
||||
dev = objclass(self.conn, parsexmlnode=devnode)
|
||||
devnodes = [
|
||||
x for x in node.children if
|
||||
(x.name in VirtualDevice.virtual_device_classes and
|
||||
x.parent == node)
|
||||
]
|
||||
for devnode in devnodes:
|
||||
objclass = VirtualDevice.virtual_device_classes[devnode.name]
|
||||
dev = objclass(self.conn, parsexmlnode=self._xml_node)
|
||||
self._track_device(dev)
|
||||
|
||||
self._xml_node.virtinst_root_doc = self._xml_root_doc
|
||||
self.os = OSXML(self.conn, parsexmlnode=self._xml_node)
|
||||
self.features = DomainFeatures(self.conn,
|
||||
parsexmlnode=self._xml_node)
|
||||
self.clock = Clock(self.conn, parsexmlnode=self._xml_node)
|
||||
self.seclabel = Seclabel(self.conn, parsexmlnode=self._xml_node)
|
||||
self.cpu = CPU(self.conn, parsexmlnode=self._xml_node)
|
||||
self.numatune = DomainNumatune(self.conn,
|
||||
parsexmlnode=self._xml_node)
|
||||
self._recalculate_device_xpaths()
|
||||
|
||||
def _recalculate_device_xpaths(self):
|
||||
count = {}
|
||||
for dev in self.get_all_devices():
|
||||
devtype = dev.virtual_device_type
|
||||
if devtype not in count:
|
||||
count[devtype] = 1
|
||||
newpath = "./devices/%s[%d]" % (devtype, count[devtype])
|
||||
dev.set_root_xpath(newpath)
|
||||
count[devtype] += 1
|
||||
|
||||
|
||||
def add_default_input_device(self):
|
||||
if self.os.is_container():
|
||||
@ -573,15 +551,7 @@ class Guest(XMLBuilder):
|
||||
self.bootloader = "/usr/bin/pygrub"
|
||||
self.os.clear()
|
||||
|
||||
count = {}
|
||||
for dev in self.get_all_devices():
|
||||
devtype = dev.virtual_device_type
|
||||
if devtype not in count:
|
||||
count[devtype] = 1
|
||||
newpath = "./devices/%s[%d]" % (devtype, count[devtype])
|
||||
setattr(dev, "_XML_NEW_ROOT_PATH", newpath)
|
||||
count[devtype] += 1
|
||||
|
||||
self._recalculate_device_xpaths()
|
||||
return self._make_xml_stub()
|
||||
|
||||
def get_continue_inst(self):
|
||||
@ -875,7 +845,7 @@ class Guest(XMLBuilder):
|
||||
# Keep cdrom around, but with no media attached,
|
||||
# But only if we are a distro that doesn't have a multi
|
||||
# stage install (aka not Windows)
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
return (d.virtual_device_type == "disk" and
|
||||
d.device == VirtualDisk.DEVICE_CDROM
|
||||
and d.transient
|
||||
and not install and
|
||||
@ -883,7 +853,7 @@ class Guest(XMLBuilder):
|
||||
|
||||
def do_skip_disk(d):
|
||||
# Skip transient labeled non-media disks
|
||||
return (d.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
return (d.virtual_device_type == "disk" and
|
||||
d.device == VirtualDisk.DEVICE_DISK
|
||||
and d.transient
|
||||
and not install)
|
||||
@ -942,17 +912,15 @@ class Guest(XMLBuilder):
|
||||
self.os.bootorder = []
|
||||
|
||||
def _set_hvm_defaults(self):
|
||||
disktype = VirtualDevice.VIRTUAL_DEV_DISK
|
||||
nettype = VirtualDevice.VIRTUAL_DEV_NET
|
||||
disk_bus = self._lookup_device_param(disktype, "bus")
|
||||
net_model = self._lookup_device_param(nettype, "model")
|
||||
disk_bus = self._lookup_device_param("disk", "bus")
|
||||
net_model = self._lookup_device_param("interface", "model")
|
||||
|
||||
# Only overwrite params if they weren't already specified
|
||||
for net in self.get_devices(nettype):
|
||||
for net in self.get_devices("interface"):
|
||||
if net_model and not net.model:
|
||||
net.model = net_model
|
||||
|
||||
for disk in self.get_devices(disktype):
|
||||
for disk in self.get_devices("disk"):
|
||||
if (disk_bus and not disk.bus and
|
||||
disk.device == VirtualDisk.DEVICE_DISK):
|
||||
disk.bus = disk_bus
|
||||
@ -966,13 +934,13 @@ class Guest(XMLBuilder):
|
||||
|
||||
def _set_pv_defaults(self):
|
||||
# Default file backed PV guests to tap driver
|
||||
for d in self.get_devices(VirtualDevice.VIRTUAL_DEV_DISK):
|
||||
for d in self.get_devices("disk"):
|
||||
if (d.type == VirtualDisk.TYPE_FILE
|
||||
and d.driver_name is None
|
||||
and util.is_blktap_capable(self.conn)):
|
||||
d.driver_name = VirtualDisk.DRIVER_TAP
|
||||
|
||||
for d in self.get_devices(VirtualDevice.VIRTUAL_DEV_INPUT):
|
||||
for d in self.get_devices("input"):
|
||||
if d.type == d.TYPE_DEFAULT:
|
||||
d.type = d.TYPE_MOUSE
|
||||
if d.bus == d.BUS_DEFAULT:
|
||||
@ -1001,7 +969,7 @@ class Guest(XMLBuilder):
|
||||
|
||||
# Add spapr-vio controller if needed
|
||||
if (dev.address.type == "spapr-vio" and
|
||||
dev.virtual_device_type == VirtualDevice.VIRTUAL_DEV_DISK and
|
||||
dev.virtual_device_type == "disk" and
|
||||
not any([cont.address.type == "spapr-vio" for cont in
|
||||
self.get_devices("controller")])):
|
||||
ctrl = virtinst.VirtualController(self.conn)
|
||||
@ -1015,16 +983,10 @@ class Guest(XMLBuilder):
|
||||
if self.os.is_xenpv():
|
||||
self._set_pv_defaults()
|
||||
|
||||
soundtype = VirtualDevice.VIRTUAL_DEV_AUDIO
|
||||
videotype = VirtualDevice.VIRTUAL_DEV_VIDEO
|
||||
inputtype = VirtualDevice.VIRTUAL_DEV_INPUT
|
||||
gfxtype = VirtualDevice.VIRTUAL_DEV_GRAPHICS
|
||||
channeltype = VirtualDevice.VIRTUAL_DEV_CHANNEL
|
||||
|
||||
# Set default input values
|
||||
input_type = self._lookup_device_param(inputtype, "type")
|
||||
input_bus = self._lookup_device_param(inputtype, "bus")
|
||||
for inp in self.get_devices(inputtype):
|
||||
input_type = self._lookup_device_param("input", "type")
|
||||
input_bus = self._lookup_device_param("input", "bus")
|
||||
for inp in self.get_devices("input"):
|
||||
if (inp.type == inp.TYPE_DEFAULT and
|
||||
inp.bus == inp.BUS_DEFAULT):
|
||||
inp.type = input_type
|
||||
@ -1032,7 +994,7 @@ class Guest(XMLBuilder):
|
||||
|
||||
# Generate disk targets, and set preferred disk bus
|
||||
used_targets = []
|
||||
for disk in self.get_devices(VirtualDevice.VIRTUAL_DEV_DISK):
|
||||
for disk in self.get_devices("disk"):
|
||||
if not disk.bus:
|
||||
if disk.device == disk.DEVICE_FLOPPY:
|
||||
disk.bus = "fdc"
|
||||
@ -1051,29 +1013,29 @@ class Guest(XMLBuilder):
|
||||
used_targets.append(disk.generate_target(used_targets))
|
||||
|
||||
# Set sound device model
|
||||
sound_model = self._lookup_device_param(soundtype, "model")
|
||||
for sound in self.get_devices(soundtype):
|
||||
sound_model = self._lookup_device_param("sound", "model")
|
||||
for sound in self.get_devices("sound"):
|
||||
if sound.model == sound.MODEL_DEFAULT:
|
||||
sound.model = sound_model
|
||||
|
||||
# Set video device model
|
||||
# QXL device (only if we use spice) - safe even if guest is VGA only
|
||||
def has_spice():
|
||||
for gfx in self.get_devices(gfxtype):
|
||||
for gfx in self.get_devices("graphics"):
|
||||
if gfx.type == gfx.TYPE_SPICE:
|
||||
return True
|
||||
if has_spice():
|
||||
video_model = "qxl"
|
||||
video_model = "qxl"
|
||||
else:
|
||||
video_model = self._lookup_device_param(videotype, "model")
|
||||
video_model = self._lookup_device_param("video", "model")
|
||||
|
||||
for video in self.get_devices(videotype):
|
||||
for video in self.get_devices("video"):
|
||||
if video.model == video.MODEL_DEFAULT:
|
||||
video.model = video_model
|
||||
|
||||
# Spice agent channel (only if we use spice)
|
||||
def has_spice_agent():
|
||||
for chn in self.get_devices(channeltype):
|
||||
for chn in self.get_devices("channel"):
|
||||
if chn.type == chn.TYPE_SPICEVMC:
|
||||
return True
|
||||
|
||||
|
@ -30,3 +30,5 @@ class VirtualAudio(VirtualDevice):
|
||||
model = XMLProperty(xpath="./@model",
|
||||
default_cb=lambda s: "es1370",
|
||||
default_name=MODEL_DEFAULT)
|
||||
|
||||
VirtualAudio.register_type()
|
||||
|
@ -150,7 +150,12 @@ class _VirtualCharDevice(VirtualDevice):
|
||||
xpath="./@type")
|
||||
|
||||
def _sourcepath_get_xpath(self):
|
||||
return "./source/@path | ./@tty"
|
||||
ret = "./source/@path"
|
||||
for xpath in [ret, "./@tty"]:
|
||||
if self._xml_ctx.xpathEval(self.fix_relative_xpath(xpath)):
|
||||
ret = xpath
|
||||
break
|
||||
return ret
|
||||
source_path = XMLProperty(make_getter_xpath_cb=_sourcepath_get_xpath,
|
||||
doc=_("Host input path to attach to the guest."),
|
||||
xpath="./source/@path")
|
||||
@ -263,3 +268,9 @@ class VirtualParallelDevice(_VirtualCharDevice):
|
||||
class VirtualChannelDevice(_VirtualCharDevice):
|
||||
virtual_device_type = "channel"
|
||||
TYPES = [_VirtualCharDevice.TYPE_SPICEVMC]
|
||||
|
||||
|
||||
VirtualConsoleDevice.register_type()
|
||||
VirtualSerialDevice.register_type()
|
||||
VirtualParallelDevice.register_type()
|
||||
VirtualChannelDevice.register_type()
|
||||
|
@ -91,3 +91,5 @@ class VirtualController(VirtualDevice):
|
||||
master_startport = XMLProperty(xpath="./master/@startport", is_int=True)
|
||||
|
||||
index = XMLProperty(xpath="./@index", is_int=True, default_cb=lambda s: 0)
|
||||
|
||||
VirtualController.register_type()
|
||||
|
@ -19,6 +19,7 @@
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
import virtinst
|
||||
from virtinst.xmlbuilder import XMLBuilder, XMLProperty
|
||||
|
||||
|
||||
@ -67,6 +68,12 @@ class VirtualDevice(XMLBuilder):
|
||||
VIRTUAL_DEV_MEMBALLOON,
|
||||
VIRTUAL_DEV_TPM]
|
||||
|
||||
virtual_device_classes = {}
|
||||
|
||||
@classmethod
|
||||
def register_type(c):
|
||||
VirtualDevice.virtual_device_classes[c.virtual_device_type] = c
|
||||
|
||||
# General device type (disk, interface, etc.)
|
||||
virtual_device_type = None
|
||||
_XML_INDENT = 4
|
||||
|
@ -398,9 +398,7 @@ class VirtualDisk(VirtualDevice):
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
|
||||
|
||||
self._storage_backend = diskbackend.StorageBackend(self.conn,
|
||||
self._xmlpath,
|
||||
None, None)
|
||||
self.__storage_backend = None
|
||||
self._storage_creator = None
|
||||
|
||||
self.nomanaged = False
|
||||
@ -487,7 +485,7 @@ class VirtualDisk(VirtualDevice):
|
||||
ret = "./source/@file"
|
||||
for prop in _TARGET_PROPS:
|
||||
xpath = "./source/@" + prop
|
||||
if self._xml_ctx.xpathEval(xpath):
|
||||
if self._xml_ctx.xpathEval(self.fix_relative_xpath(xpath)):
|
||||
ret = xpath
|
||||
break
|
||||
return ret
|
||||
@ -531,6 +529,16 @@ class VirtualDisk(VirtualDevice):
|
||||
# Validation assistance methods #
|
||||
#################################
|
||||
|
||||
def _get_storage_backend(self):
|
||||
if self.__storage_backend is None:
|
||||
self.__storage_backend = diskbackend.StorageBackend(self.conn,
|
||||
self._xmlpath,
|
||||
None, None)
|
||||
return self.__storage_backend
|
||||
def _set_storage_backend(self, val):
|
||||
self.__storage_backend = val
|
||||
_storage_backend = property(_get_storage_backend, _set_storage_backend)
|
||||
|
||||
def set_create_storage(self, size=None, sparse=True,
|
||||
fmt=None, vol_install=None, clone_path=None,
|
||||
fake=False):
|
||||
@ -543,8 +551,6 @@ class VirtualDisk(VirtualDevice):
|
||||
@fake: If true, make like we are creating storage but fail
|
||||
if we ever asked to do so.
|
||||
"""
|
||||
if self._is_parse():
|
||||
raise ValueError("Cannot create storage for a parsed disk.")
|
||||
path = self.path
|
||||
|
||||
# Validate clone_path
|
||||
@ -841,3 +847,5 @@ class VirtualDisk(VirtualDevice):
|
||||
self.target = t
|
||||
return self.target
|
||||
raise ValueError(_("No more space for disks of type '%s'" % prefix))
|
||||
|
||||
VirtualDisk.register_type()
|
||||
|
@ -91,9 +91,8 @@ class VirtualFilesystem(VirtualDevice):
|
||||
ret = "./source/@dir"
|
||||
for prop in self._target_props:
|
||||
xpath = "./source/@" + prop
|
||||
if self._xml_ctx.xpathEval(xpath):
|
||||
if self._xml_ctx.xpathEval(self.fix_relative_xpath(xpath)):
|
||||
ret = xpath
|
||||
|
||||
return ret
|
||||
def _xml_set_source_xpath(self):
|
||||
ret = "./source/@" + self.type_to_source_prop(self.type)
|
||||
@ -116,3 +115,6 @@ class VirtualFilesystem(VirtualDevice):
|
||||
return val
|
||||
target = XMLProperty(xpath="./target/@dir",
|
||||
set_converter=_validate_set_target)
|
||||
|
||||
|
||||
VirtualFilesystem.register_type()
|
||||
|
@ -180,3 +180,6 @@ class VirtualGraphics(VirtualDevice):
|
||||
passwd = XMLProperty(xpath="./@passwd")
|
||||
passwdValidTo = XMLProperty(xpath="./@passwdValidTo")
|
||||
socket = XMLProperty(xpath="./@socket")
|
||||
|
||||
|
||||
VirtualGraphics.register_type()
|
||||
|
@ -105,3 +105,6 @@ class VirtualHostDevice(VirtualDevice):
|
||||
default_cb=_get_default_domain)
|
||||
function = XMLProperty(xpath="./source/address/@function")
|
||||
slot = XMLProperty(xpath="./source/address/@slot")
|
||||
|
||||
|
||||
VirtualHostDevice.register_type()
|
||||
|
@ -41,3 +41,6 @@ class VirtualInputDevice(VirtualDevice):
|
||||
bus = XMLProperty(xpath="./@bus",
|
||||
default_cb=lambda s: s.BUS_XEN,
|
||||
default_name=BUS_DEFAULT)
|
||||
|
||||
|
||||
VirtualInputDevice.register_type()
|
||||
|
@ -28,3 +28,6 @@ class VirtualMemballoon(VirtualDevice):
|
||||
MODELS = ["xen", "none", MODEL_DEFAULT]
|
||||
|
||||
model = XMLProperty(xpath="./@model", default_cb=lambda s: s.MODEL_DEFAULT)
|
||||
|
||||
|
||||
VirtualMemballoon.register_type()
|
||||
|
@ -202,8 +202,6 @@ class VirtualNetworkInterface(VirtualDevice):
|
||||
default_cb=lambda s: s.TYPE_BRIDGE)
|
||||
|
||||
def _get_default_mac(self):
|
||||
if self._is_parse():
|
||||
return None
|
||||
if not self._random_mac:
|
||||
self._random_mac = self.generate_mac(self.conn)
|
||||
return self._random_mac
|
||||
@ -233,3 +231,6 @@ class VirtualNetworkInterface(VirtualDevice):
|
||||
default_cb=_default_source_mode)
|
||||
model = XMLProperty(xpath="./model/@type")
|
||||
target_dev = XMLProperty(xpath="./target/@dev")
|
||||
|
||||
|
||||
VirtualNetworkInterface.register_type()
|
||||
|
@ -52,3 +52,6 @@ class VirtualRedirDevice(VirtualDevice):
|
||||
|
||||
host = XMLProperty(xpath="./source/@host")
|
||||
service = XMLProperty(xpath="./source/@service", is_int=True)
|
||||
|
||||
|
||||
VirtualRedirDevice.register_type()
|
||||
|
@ -48,3 +48,6 @@ class VirtualSmartCardDevice(VirtualDevice):
|
||||
type = XMLProperty(xpath="./@type",
|
||||
default_cb=_default_type,
|
||||
default_name=TYPE_DEFAULT)
|
||||
|
||||
|
||||
VirtualSmartCardDevice.register_type()
|
||||
|
@ -63,3 +63,6 @@ class VirtualTPMDevice(VirtualDevice):
|
||||
default_cb=lambda s: s.MODEL_TIS)
|
||||
device_path = XMLProperty(xpath="./backend/device/@path",
|
||||
default_cb=lambda s: "/dev/tpm0")
|
||||
|
||||
|
||||
VirtualTPMDevice.register_type()
|
||||
|
@ -43,3 +43,6 @@ class VirtualVideoDevice(VirtualDevice):
|
||||
vram = XMLProperty(xpath="./model/@vram", is_int=True)
|
||||
ram = XMLProperty(xpath="./model/@ram", is_int=True)
|
||||
heads = XMLProperty(xpath="./model/@heads", is_int=True)
|
||||
|
||||
|
||||
VirtualVideoDevice.register_type()
|
||||
|
@ -63,3 +63,6 @@ class VirtualWatchdog(VirtualDevice):
|
||||
action = XMLProperty(xpath="./@action",
|
||||
default_name=ACTION_DEFAULT,
|
||||
default_cb=lambda s: s.ACTION_RESET)
|
||||
|
||||
|
||||
VirtualWatchdog.register_type()
|
||||
|
@ -349,18 +349,14 @@ class XMLProperty(property):
|
||||
ret = self._xpath_for_getter_cb(xmlbuilder)
|
||||
if ret is None:
|
||||
raise RuntimeError("%s: didn't generate any setter xpath." % self)
|
||||
return self._xpath_fix_relative(xmlbuilder, ret)
|
||||
return xmlbuilder.fix_relative_xpath(ret)
|
||||
def _xpath_for_setter(self, xmlbuilder):
|
||||
ret = self._xpath
|
||||
if self._xpath_for_setter_cb:
|
||||
ret = self._xpath_for_setter_cb(xmlbuilder)
|
||||
if ret is None:
|
||||
raise RuntimeError("%s: didn't generate any setter xpath." % self)
|
||||
return self._xpath_fix_relative(xmlbuilder, ret)
|
||||
def _xpath_fix_relative(self, xmlbuilder, xpath):
|
||||
if not xmlbuilder._XML_NEW_ROOT_PATH:
|
||||
return xpath
|
||||
return "./%s%s" % (xmlbuilder._XML_NEW_ROOT_PATH, xpath.strip("."))
|
||||
return xmlbuilder.fix_relative_xpath(ret)
|
||||
|
||||
|
||||
def _xpath_list_for_setter(self, xpath, setval, nodelist):
|
||||
@ -411,6 +407,7 @@ class XMLProperty(property):
|
||||
clear_nodes = []
|
||||
|
||||
for cpath in self._setter_clear_these_first:
|
||||
cpath = xmlbuilder.fix_relative_xpath(cpath)
|
||||
cnode = _get_xpath_node(root_ctx, cpath, False)
|
||||
if not cnode:
|
||||
continue
|
||||
@ -506,10 +503,9 @@ class XMLProperty(property):
|
||||
##################################
|
||||
|
||||
def getter(self, xmlbuilder):
|
||||
fgetval = self._nonxml_fget(xmlbuilder)
|
||||
|
||||
root_node = getattr(xmlbuilder, "_xml_node")
|
||||
if root_node is None:
|
||||
fgetval = self._nonxml_fget(xmlbuilder)
|
||||
return self._convert_get_value(fgetval, initial=True)
|
||||
|
||||
xpath = self._xpath_for_getter(xmlbuilder)
|
||||
@ -585,9 +581,6 @@ class XMLBuilder(object):
|
||||
# Integer indentation level for generated XML.
|
||||
_XML_INDENT = None
|
||||
|
||||
# This is only used to make device XML work for guest XML generating
|
||||
_XML_NEW_ROOT_PATH = ""
|
||||
|
||||
_dumpxml_xpath = "."
|
||||
|
||||
def __init__(self, conn, parsexml=None, parsexmlnode=None):
|
||||
@ -600,8 +593,9 @@ class XMLBuilder(object):
|
||||
@type parsexml: C{str}
|
||||
@param parsexmlnode: Option xpathNode to use
|
||||
"""
|
||||
self._conn = conn
|
||||
self.conn = conn
|
||||
|
||||
self._xml_root_xpath = ""
|
||||
self._xml_node = None
|
||||
self._xml_ctx = None
|
||||
self._xml_root_doc = None
|
||||
@ -622,17 +616,38 @@ class XMLBuilder(object):
|
||||
ret._proporder = ret._proporder[:]
|
||||
return ret
|
||||
|
||||
def _get_conn(self):
|
||||
return self._conn
|
||||
conn = property(_get_conn)
|
||||
def set_new_xml(self, xml):
|
||||
self._parsexml(xml, None)
|
||||
|
||||
def set_xml_node(self, node):
|
||||
self._parsexml(None, node)
|
||||
def set_root_xpath(self, xpath):
|
||||
self._xml_root_xpath = xpath
|
||||
|
||||
def get_xml_node_path(self):
|
||||
if self._xml_node:
|
||||
return self._xml_node.nodePath()
|
||||
return None
|
||||
xmlprops = self.all_xml_props()
|
||||
for propname in self._XML_PROP_ORDER:
|
||||
if propname in self.all_xml_props():
|
||||
continue
|
||||
for prop in util.listify(getattr(self, propname)):
|
||||
prop.set_root_xpath(xpath)
|
||||
|
||||
def get_root_xpath(self):
|
||||
return self._xml_root_xpath
|
||||
|
||||
def fix_relative_xpath(self, xpath):
|
||||
if not self._xml_root_xpath:
|
||||
return xpath
|
||||
return "%s%s" % (self._xml_root_xpath, xpath.strip("."))
|
||||
|
||||
def get_xml_config(self, *args, **kwargs):
|
||||
data = self._prepare_get_xml()
|
||||
try:
|
||||
return self._do_get_xml_config(self._dumpxml_xpath, True,
|
||||
*args, **kwargs)
|
||||
finally:
|
||||
self._finish_get_xml(data)
|
||||
|
||||
def clear(self):
|
||||
for prop in self.all_xml_props().values():
|
||||
prop._clear(self)
|
||||
|
||||
def _do_get_xml_config(self, dumpxml_xpath, clean, *args, **kwargs):
|
||||
"""
|
||||
@ -661,18 +676,6 @@ class XMLBuilder(object):
|
||||
ret = self._cleanup_xml(ret)
|
||||
return ret
|
||||
|
||||
def get_xml_config(self, *args, **kwargs):
|
||||
data = self._prepare_get_xml()
|
||||
try:
|
||||
return self._do_get_xml_config(self._dumpxml_xpath, True,
|
||||
*args, **kwargs)
|
||||
finally:
|
||||
self._finish_get_xml(data)
|
||||
|
||||
def clear(self):
|
||||
for prop in self.all_xml_props().values():
|
||||
prop._clear(self)
|
||||
|
||||
|
||||
#######################
|
||||
# Internal helper API #
|
||||
@ -727,7 +730,13 @@ class XMLBuilder(object):
|
||||
return ""
|
||||
return _indent("<%s/>" % (self._XML_ROOT_NAME), self._XML_INDENT)
|
||||
|
||||
def _add_child_node(self, parent_xpath, newnode):
|
||||
def _add_child(self, parent_xpath, dev):
|
||||
"""
|
||||
Insert the passed XMLBuilder object into our XML document at the
|
||||
specified path
|
||||
"""
|
||||
dev.set_new_xml(dev.get_xml_config())
|
||||
newnode = dev._xml_node
|
||||
ret = _build_xpath_node(self._xml_ctx, parent_xpath, newnode)
|
||||
return ret
|
||||
|
||||
@ -746,6 +755,10 @@ class XMLBuilder(object):
|
||||
doc = libxml2.parseDoc(xml)
|
||||
self._xml_root_doc = _DocCleanupWrapper(doc)
|
||||
self._xml_node = doc.children
|
||||
|
||||
# This just stores a reference to our root doc wrapper in
|
||||
# the root node, so when the node goes away it triggers
|
||||
# auto free'ing of the doc
|
||||
self._xml_node.virtinst_root_doc = self._xml_root_doc
|
||||
else:
|
||||
self._xml_node = node
|
||||
@ -800,8 +813,8 @@ class XMLBuilder(object):
|
||||
validate=False)
|
||||
else:
|
||||
for obj in util.listify(getattr(self, key)):
|
||||
if self._XML_NEW_ROOT_PATH and not obj._XML_NEW_ROOT_PATH:
|
||||
obj._XML_NEW_ROOT_PATH = self._XML_NEW_ROOT_PATH
|
||||
if self._xml_root_xpath and not obj._xml_root_xpath:
|
||||
obj._xml_root_xpath = self._xml_root_xpath
|
||||
obj._add_parse_bits(xml=None, node=self._xml_node)
|
||||
|
||||
xml = self._do_get_xml_config(".", clean).strip("\n")
|
||||
|
Loading…
Reference in New Issue
Block a user