mirror of
https://github.com/virt-manager/virt-manager.git
synced 2025-08-24 17:49:33 +03:00
xmlbuilder: centralize adding child new child prop instances
Currently the domain CPU class has a child property like: siblings = XMLChildProperty(_CPUCellSibling) If a user wants to add a new sibling, we add a convenience function: def add_sibling(self): obj = _CPUCellSibling(self.conn) self.add_child(obj) return obj Rather than require every child property to define a similar matching helper function, this adds infrastructure in xmlbuilder to do this generically for every child property. Now callers can do obj = guest.cpu.siblings.add_new()
This commit is contained in:
@ -40,7 +40,8 @@ def createPool(conn, ptype, poolname=None, fmt=None, target_path=None,
|
||||
pool_inst.type = ptype
|
||||
|
||||
if pool_inst.supports_property("hosts"):
|
||||
pool_inst.add_host("some.random.hostname")
|
||||
hostobj = pool_inst.hosts.add_new()
|
||||
hostobj.name = "some.random.hostname"
|
||||
if pool_inst.supports_property("source_path"):
|
||||
pool_inst.source_path = source_path or "/some/source/path"
|
||||
if pool_inst.supports_property("target_path"):
|
||||
|
@ -120,11 +120,11 @@ class XMLParseTest(unittest.TestCase):
|
||||
|
||||
check = self._make_checker(guest.clock)
|
||||
check("offset", "utc", "localtime")
|
||||
guest.clock.remove_timer(guest.clock.timers[0])
|
||||
guest.clock.remove_child(guest.clock.timers[0])
|
||||
check = self._make_checker(guest.clock.timers[0])
|
||||
check("name", "pit", "rtc")
|
||||
check("tickpolicy", "delay", "merge")
|
||||
timer = guest.clock.add_timer()
|
||||
timer = guest.clock.timers.add_new()
|
||||
check = self._make_checker(timer)
|
||||
check("name", None, "hpet")
|
||||
check("present", None, False)
|
||||
@ -180,7 +180,7 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("name", "x2apic")
|
||||
check("policy", "force", "disable")
|
||||
rmfeat = guest.cpu.features[3]
|
||||
guest.cpu.remove_feature(rmfeat)
|
||||
guest.cpu.remove_child(rmfeat)
|
||||
self.assertEqual(rmfeat.get_xml_config(),
|
||||
"""<feature name="foo" policy="bar"/>\n""")
|
||||
guest.cpu.add_feature("addfeature")
|
||||
@ -1196,7 +1196,9 @@ class XMLParseTest(unittest.TestCase):
|
||||
check = self._make_checker(pool.hosts[2])
|
||||
check("name", "ceph-mon-3.example.com")
|
||||
check("port", 6789, 1000)
|
||||
pool.add_host("frobber", "5555")
|
||||
hostobj = pool.hosts.add_new()
|
||||
hostobj.name = "frobber"
|
||||
hostobj.port = "5555"
|
||||
|
||||
utils.diff_compare(pool.get_xml_config(), outfile)
|
||||
utils.test_create(conn, pool.get_xml_config(), "storagePoolDefineXML")
|
||||
@ -1287,7 +1289,7 @@ class XMLParseTest(unittest.TestCase):
|
||||
check("family", "ipv6", "ipv6")
|
||||
check("prefix", 64, 63)
|
||||
|
||||
r = net.add_route()
|
||||
r = net.routes.add_new()
|
||||
r.family = "ipv4"
|
||||
r.address = "192.168.8.0"
|
||||
r.prefix = "24"
|
||||
|
@ -756,7 +756,7 @@ class vmmCreateNetwork(vmmGObjectUI):
|
||||
|
||||
if net.forward.mode == "hostdev":
|
||||
net.forward.managed = "yes"
|
||||
pfobj = net.forward.add_pf()
|
||||
pfobj = net.forward.pfs.add_new()
|
||||
pfobj.dev = net.forward.dev
|
||||
net.forward.dev = None
|
||||
net.domain_name = None
|
||||
@ -765,12 +765,12 @@ class vmmCreateNetwork(vmmGObjectUI):
|
||||
|
||||
if self.get_config_ipv4_enable():
|
||||
ip = self.get_config_ip4()
|
||||
ipobj = net.add_ip()
|
||||
ipobj = net.ips.add_new()
|
||||
ipobj.address = str(ip.network_address + 1)
|
||||
ipobj.netmask = str(ip.netmask)
|
||||
|
||||
if self.get_config_dhcpv4_enable():
|
||||
dhcpobj = ipobj.add_range()
|
||||
dhcpobj = ipobj.ranges.add_new()
|
||||
dhcpobj.start = str(
|
||||
self.get_config_dhcpv4_start().network_address
|
||||
)
|
||||
@ -778,13 +778,13 @@ class vmmCreateNetwork(vmmGObjectUI):
|
||||
|
||||
if self.get_config_ipv6_enable():
|
||||
ip = self.get_config_ip6()
|
||||
ipobj = net.add_ip()
|
||||
ipobj = net.ips.add_new()
|
||||
ipobj.family = "ipv6"
|
||||
ipobj.address = str(ip.network_address + 1)
|
||||
ipobj.prefix = str(ip.prefixlen)
|
||||
|
||||
if self.get_config_dhcpv6_enable():
|
||||
dhcpobj = ipobj.add_range()
|
||||
dhcpobj = ipobj.ranges.add_new()
|
||||
dhcpobj.start = str(
|
||||
self.get_config_dhcpv6_start().network_address
|
||||
)
|
||||
@ -795,7 +795,7 @@ class vmmCreateNetwork(vmmGObjectUI):
|
||||
netaddr = _make_ipaddr(self.get_config_routev4_network())
|
||||
gwaddr = _make_ipaddr(self.get_config_routev4_gateway())
|
||||
if netaddr and gwaddr:
|
||||
route = net.add_route()
|
||||
route = net.routes.add_new()
|
||||
route.family = "ipv4"
|
||||
route.address = netaddr.network_address
|
||||
route.prefix = netaddr.prefixlen
|
||||
@ -804,7 +804,7 @@ class vmmCreateNetwork(vmmGObjectUI):
|
||||
netaddr = _make_ipaddr(self.get_config_routev6_network())
|
||||
gwaddr = _make_ipaddr(self.get_config_routev6_gateway())
|
||||
if netaddr and gwaddr:
|
||||
route = net.add_route()
|
||||
route = net.routes.add_new()
|
||||
route.family = "ipv6"
|
||||
route.address = netaddr.network_address
|
||||
route.prefix = netaddr.prefixlen
|
||||
|
@ -514,7 +514,8 @@ class vmmCreatePool(vmmGObjectUI):
|
||||
try:
|
||||
self._pool.target_path = target
|
||||
if host:
|
||||
self._pool.add_host(host)
|
||||
hostobj = self._pool.hosts.add_new()
|
||||
hostobj.name = host
|
||||
if source:
|
||||
self._pool.source_path = source
|
||||
if fmt:
|
||||
|
@ -1143,7 +1143,7 @@ class VirtCLIParser(object):
|
||||
# end of the domain XML, which gives an ugly diff
|
||||
clear_inst.clear(leave_stub="," in self.optstr)
|
||||
|
||||
def _make_find_inst_cb(self, cliarg, objpropname, objaddfn):
|
||||
def _make_find_inst_cb(self, cliarg, objpropname):
|
||||
"""
|
||||
Create a callback used for find_inst_cb command line lookup.
|
||||
|
||||
@ -1152,9 +1152,6 @@ class VirtCLIParser(object):
|
||||
:param objpropname: The property name on the virtinst object that
|
||||
this parameter maps too. For the seclabel example, we want
|
||||
disk.seclabels, so this value is 'seclabels'
|
||||
:param objaddfn: The function name for adding a new instance of
|
||||
this parameter to the virtinst object. For the seclabel example,
|
||||
we want disk.add_seclabel(), so this value is "add_seclabels"
|
||||
"""
|
||||
def cb(inst, val, virtarg, can_edit):
|
||||
ignore = val
|
||||
@ -1165,7 +1162,7 @@ class VirtCLIParser(object):
|
||||
|
||||
if can_edit:
|
||||
while len(getattr(inst, objpropname)) < (num + 1):
|
||||
getattr(inst, objaddfn)()
|
||||
getattr(inst, objpropname).add_new()
|
||||
try:
|
||||
return getattr(inst, objpropname)[num]
|
||||
except IndexError:
|
||||
@ -1465,8 +1462,7 @@ class ParserCPU(VirtCLIParser):
|
||||
def cell_find_inst_cb(self, *args, **kwargs):
|
||||
cliarg = "cell" # cell[0-9]*
|
||||
objpropname = "cells" # cpu.cells
|
||||
objaddfn = "add_cell" # cpu.add_cell
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname, objaddfn)
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname)
|
||||
return cb(*args, **kwargs)
|
||||
|
||||
def sibling_find_inst_cb(self, inst, *args, **kwargs):
|
||||
@ -1475,8 +1471,7 @@ class ParserCPU(VirtCLIParser):
|
||||
|
||||
cliarg = "sibling" # cell[0-9]*.distances.sibling[0-9]*
|
||||
objpropname = "siblings" # cell.siblings
|
||||
objaddfn = "add_sibling" # cell.add_sibling
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname, objaddfn)
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname)
|
||||
return cb(inst, *args, **kwargs)
|
||||
|
||||
def set_model_cb(self, inst, val, virtarg):
|
||||
@ -1508,8 +1503,8 @@ class ParserCPU(VirtCLIParser):
|
||||
def set_l3_cache_cb(self, inst, val, virtarg, can_edit):
|
||||
cpu = inst
|
||||
|
||||
if can_edit:
|
||||
cpu.set_l3_cache_mode()
|
||||
if can_edit and not cpu.cache:
|
||||
cpu.cache.add_new()
|
||||
try:
|
||||
return cpu.cache[0]
|
||||
except IndexError:
|
||||
@ -1580,8 +1575,7 @@ class ParserCPUTune(VirtCLIParser):
|
||||
def vcpu_find_inst_cb(self, *args, **kwargs):
|
||||
cliarg = "vcpupin" # vcpupin[0-9]*
|
||||
objpropname = "vcpus"
|
||||
objaddfn = "add_vcpu"
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname, objaddfn)
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname)
|
||||
return cb(*args, **kwargs)
|
||||
|
||||
_register_virt_parser(ParserCPUTune)
|
||||
@ -1823,7 +1817,7 @@ class ParserClock(VirtCLIParser):
|
||||
break
|
||||
|
||||
if not timerobj:
|
||||
timerobj = inst.add_timer()
|
||||
timerobj = inst.timers.add_new()
|
||||
timerobj.name = tname
|
||||
|
||||
setattr(timerobj, attrname, val)
|
||||
@ -1928,11 +1922,14 @@ class ParserQemuCLI(VirtCLIParser):
|
||||
|
||||
def args_cb(self, inst, val, virtarg):
|
||||
for opt in shlex.split(val):
|
||||
inst.add_arg(opt)
|
||||
obj = inst.args.add_new()
|
||||
obj.value = opt
|
||||
|
||||
def env_cb(self, inst, val, virtarg):
|
||||
name, envval = val.split("=", 1)
|
||||
inst.add_env(name, envval)
|
||||
obj = inst.envs.add_new()
|
||||
obj.name = name
|
||||
obj.value = envval
|
||||
|
||||
def _parse(self, inst):
|
||||
self.optdict.clear()
|
||||
@ -2023,8 +2020,7 @@ class ParserDisk(VirtCLIParser):
|
||||
def seclabel_find_inst_cb(self, *args, **kwargs):
|
||||
cliarg = "seclabel" # seclabel[0-9]*
|
||||
objpropname = "seclabels" # disk.seclabels
|
||||
objaddfn = "add_seclabel" # disk.add_seclabel
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname, objaddfn)
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname)
|
||||
return cb(*args, **kwargs)
|
||||
|
||||
def _parse(self, inst):
|
||||
@ -2303,7 +2299,7 @@ class ParserGraphics(VirtCLIParser):
|
||||
inst.set_listen_none()
|
||||
elif val == "socket":
|
||||
inst.remove_all_listens()
|
||||
obj = inst.add_listen()
|
||||
obj = inst.listens.add_new()
|
||||
obj.type = "socket"
|
||||
else:
|
||||
inst.listen = val
|
||||
@ -2311,8 +2307,7 @@ class ParserGraphics(VirtCLIParser):
|
||||
def listens_find_inst_cb(self, *args, **kwargs):
|
||||
cliarg = "listens" # listens[0-9]*
|
||||
objpropname = "listens" # graphics.listens
|
||||
objaddfn = "add_listen" # graphics.add_listen
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname, objaddfn)
|
||||
cb = self._make_find_inst_cb(cliarg, objpropname)
|
||||
return cb(*args, **kwargs)
|
||||
|
||||
def _parse(self, inst):
|
||||
|
@ -36,10 +36,3 @@ class Clock(XMLBuilder):
|
||||
|
||||
offset = XMLProperty("./@offset")
|
||||
timers = XMLChildProperty(_ClockTimer)
|
||||
|
||||
def add_timer(self):
|
||||
obj = _ClockTimer(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
def remove_timer(self, obj):
|
||||
self.remove_child(obj)
|
||||
|
@ -43,11 +43,6 @@ class _CPUCell(XMLBuilder):
|
||||
memory = XMLProperty("./@memory", is_int=True)
|
||||
siblings = XMLChildProperty(_CPUCellSibling, relative_xpath="./distances")
|
||||
|
||||
def add_sibling(self):
|
||||
obj = _CPUCellSibling(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
||||
|
||||
class CPUCache(XMLBuilder):
|
||||
"""
|
||||
@ -103,7 +98,7 @@ class CPU(XMLBuilder):
|
||||
self.vendor = None
|
||||
self.model_fallback = None
|
||||
for f in self.features:
|
||||
self.remove_feature(f)
|
||||
self.remove_child(f)
|
||||
self.mode = val
|
||||
elif val == self.SPECIAL_MODE_HOST_COPY:
|
||||
self.copy_host_cpu()
|
||||
@ -121,26 +116,13 @@ class CPU(XMLBuilder):
|
||||
self.special_mode_was_set = True
|
||||
|
||||
def add_feature(self, name, policy="require"):
|
||||
feature = CPUFeature(self.conn)
|
||||
feature = self.features.add_new()
|
||||
feature.name = name
|
||||
feature.policy = policy
|
||||
|
||||
self.add_child(feature)
|
||||
def remove_feature(self, feature):
|
||||
self.remove_child(feature)
|
||||
features = XMLChildProperty(CPUFeature)
|
||||
|
||||
cells = XMLChildProperty(_CPUCell, relative_xpath="./numa")
|
||||
def add_cell(self):
|
||||
obj = _CPUCell(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
||||
cache = XMLChildProperty(CPUCache)
|
||||
def set_l3_cache_mode(self):
|
||||
obj = CPUCache(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
||||
def copy_host_cpu(self):
|
||||
"""
|
||||
@ -157,7 +139,7 @@ class CPU(XMLBuilder):
|
||||
self.vendor = cpu.vendor
|
||||
|
||||
for feature in self.features:
|
||||
self.remove_feature(feature)
|
||||
self.remove_child(feature)
|
||||
for feature in cpu.features:
|
||||
self.add_feature(feature.name)
|
||||
|
||||
|
@ -34,7 +34,3 @@ class CPUTune(XMLBuilder):
|
||||
"""
|
||||
_XML_ROOT_NAME = "cputune"
|
||||
vcpus = XMLChildProperty(_VCPUPin)
|
||||
def add_vcpu(self):
|
||||
obj = _VCPUPin(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
@ -600,15 +600,6 @@ class VirtualDisk(VirtualDevice):
|
||||
auth_secret_type = XMLProperty("./auth/secret/@type")
|
||||
auth_secret_uuid = XMLProperty("./auth/secret/@uuid")
|
||||
|
||||
def add_host(self, name, port):
|
||||
obj = _Host(self.conn)
|
||||
obj.name = name
|
||||
obj.port = port
|
||||
self.add_child(obj)
|
||||
|
||||
def remove_host(self, obj):
|
||||
self.remove_child(obj)
|
||||
|
||||
hosts = XMLChildProperty(_Host, relative_xpath="./source")
|
||||
|
||||
source_name = XMLProperty("./source/@name")
|
||||
@ -651,7 +642,9 @@ class VirtualDisk(VirtualDevice):
|
||||
self.source_host_name = poolxml.hosts[0].name
|
||||
self.source_host_port = poolxml.hosts[0].port
|
||||
for host in poolxml.hosts:
|
||||
self.add_host(host.name, host.port)
|
||||
obj = self.hosts.add_new()
|
||||
obj.name = host.name
|
||||
obj.port = host.port
|
||||
|
||||
path = ""
|
||||
if poolxml.source_name:
|
||||
@ -792,10 +785,6 @@ class VirtualDisk(VirtualDevice):
|
||||
iotune_wis = XMLProperty("./iotune/write_iops_sec", is_int=True)
|
||||
|
||||
seclabels = XMLChildProperty(_DiskSeclabel, relative_xpath="./source")
|
||||
def add_seclabel(self):
|
||||
obj = _DiskSeclabel(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
||||
|
||||
#################################
|
||||
|
@ -223,11 +223,6 @@ class VirtualGraphics(VirtualDevice):
|
||||
for listen in self.listens:
|
||||
self.remove_child(listen)
|
||||
|
||||
def add_listen(self):
|
||||
obj = _GraphicsListen(self.conn)
|
||||
self.add_child(obj)
|
||||
return obj
|
||||
|
||||
def get_first_listen_type(self):
|
||||
if len(self.listens) > 0:
|
||||
return self.listens[0].type
|
||||
@ -243,7 +238,7 @@ class VirtualGraphics(VirtualDevice):
|
||||
|
||||
if self.conn.check_support(
|
||||
self.conn.SUPPORT_CONN_GRAPHICS_LISTEN_NONE):
|
||||
obj = self.add_listen()
|
||||
obj = self.listens.add_new()
|
||||
obj.type = "none"
|
||||
|
||||
# Spice bits
|
||||
|
@ -844,15 +844,15 @@ class Guest(XMLBuilder):
|
||||
#
|
||||
# This is what has been recommended by the RH qemu guys :)
|
||||
|
||||
rtc = self.clock.add_timer()
|
||||
rtc = self.clock.timers.add_new()
|
||||
rtc.name = "rtc"
|
||||
rtc.tickpolicy = "catchup"
|
||||
|
||||
pit = self.clock.add_timer()
|
||||
pit = self.clock.timers.add_new()
|
||||
pit.name = "pit"
|
||||
pit.tickpolicy = "delay"
|
||||
|
||||
hpet = self.clock.add_timer()
|
||||
hpet = self.clock.timers.add_new()
|
||||
hpet.name = "hpet"
|
||||
hpet.present = False
|
||||
|
||||
@ -861,7 +861,7 @@ class Guest(XMLBuilder):
|
||||
|
||||
if (self._os_object.is_windows() and self._hyperv_supported() and
|
||||
(hv_clock or (self.stable_defaults() and hv_clock_rhel))):
|
||||
hyperv = self.clock.add_timer()
|
||||
hyperv = self.clock.timers.add_new()
|
||||
hyperv.name = "hypervclock"
|
||||
hyperv.present = True
|
||||
|
||||
|
@ -67,10 +67,9 @@ class InterfaceProtocol(XMLBuilder):
|
||||
#####################
|
||||
|
||||
def add_ip(self, addr, prefix=None):
|
||||
ip = _IPAddress(self.conn)
|
||||
ip = self.ips.add_new()
|
||||
ip.address = addr
|
||||
ip.prefix = prefix
|
||||
self.add_child(ip)
|
||||
def remove_ip(self, ip):
|
||||
self.remove_child(ip)
|
||||
ip.clear()
|
||||
|
@ -56,11 +56,6 @@ class _NetworkIP(XMLBuilder):
|
||||
ranges = XMLChildProperty(_NetworkDHCPRange, relative_xpath="./dhcp")
|
||||
hosts = XMLChildProperty(_NetworkDHCPHost, relative_xpath="./dhcp")
|
||||
|
||||
def add_range(self):
|
||||
r = _NetworkDHCPRange(self.conn)
|
||||
self.add_child(r)
|
||||
return r
|
||||
|
||||
|
||||
class _NetworkRoute(XMLBuilder):
|
||||
_XML_ROOT_NAME = "route"
|
||||
@ -95,11 +90,6 @@ class _NetworkForward(XMLBuilder):
|
||||
pf = XMLChildProperty(_NetworkForwardPf)
|
||||
vfs = XMLChildProperty(_NetworkForwardAddress)
|
||||
|
||||
def add_pf(self):
|
||||
r = _NetworkForwardPf(self.conn)
|
||||
self.add_child(r)
|
||||
return r
|
||||
|
||||
def pretty_desc(self):
|
||||
return Network.pretty_forward_desc(self.mode, self.dev)
|
||||
|
||||
@ -250,15 +240,6 @@ class Network(XMLBuilder):
|
||||
routes = XMLChildProperty(_NetworkRoute)
|
||||
bandwidth = XMLChildProperty(_NetworkBandwidth, is_single=True)
|
||||
|
||||
def add_ip(self):
|
||||
ip = _NetworkIP(self.conn)
|
||||
self.add_child(ip)
|
||||
return ip
|
||||
def add_route(self):
|
||||
route = _NetworkRoute(self.conn)
|
||||
self.add_child(route)
|
||||
return route
|
||||
|
||||
|
||||
##################
|
||||
# build routines #
|
||||
|
@ -86,23 +86,19 @@ class OSXML(XMLBuilder):
|
||||
self.remove_child(dev)
|
||||
|
||||
for d in newdevs:
|
||||
dev = _BootDevice(self.conn)
|
||||
dev = self._bootdevs.add_new()
|
||||
dev.dev = d
|
||||
self.add_child(dev)
|
||||
_bootdevs = XMLChildProperty(_BootDevice)
|
||||
bootorder = property(_get_bootorder, _set_bootorder)
|
||||
|
||||
initargs = XMLChildProperty(_InitArg)
|
||||
def add_initarg(self, val):
|
||||
obj = _InitArg(self.conn)
|
||||
obj.val = val
|
||||
self.add_child(obj)
|
||||
def set_initargs_string(self, argstring):
|
||||
import shlex
|
||||
for obj in self.initargs:
|
||||
self.remove_child(obj)
|
||||
for val in shlex.split(argstring):
|
||||
self.add_initarg(val)
|
||||
obj = self.initargs.add_new()
|
||||
obj.val = val
|
||||
|
||||
enable_bootmenu = XMLProperty("./bootmenu/@enable", is_yesno=True)
|
||||
useserial = XMLProperty("./bios/@useserial", is_yesno=True)
|
||||
|
@ -186,8 +186,8 @@ class StoragePool(_StorageObject):
|
||||
obj.type = pool_type
|
||||
obj.source_path = parseobj.source_path
|
||||
for h in parseobj.hosts:
|
||||
parseobj.remove_host(h)
|
||||
obj.add_host_obj(h)
|
||||
parseobj.remove_child(h)
|
||||
obj.add_child(h)
|
||||
obj.source_name = parseobj.source_name
|
||||
obj.format = parseobj.format
|
||||
|
||||
@ -421,15 +421,6 @@ class StoragePool(_StorageObject):
|
||||
target_path = XMLProperty("./target/path",
|
||||
default_cb=_get_default_target_path)
|
||||
|
||||
def add_host_obj(self, obj):
|
||||
self.add_child(obj)
|
||||
def add_host(self, name, port=None):
|
||||
obj = _Host(self.conn)
|
||||
obj.name = name
|
||||
obj.port = port
|
||||
self.add_child(obj)
|
||||
def remove_host(self, obj):
|
||||
self.remove_child(obj)
|
||||
hosts = XMLChildProperty(_Host, relative_xpath="./source")
|
||||
|
||||
|
||||
|
@ -298,6 +298,34 @@ def _remove_xpath_node(ctx, xpath, dofree=True):
|
||||
node.freeNode()
|
||||
|
||||
|
||||
class _XMLChildList(list):
|
||||
"""
|
||||
Little wrapper for a list containing XMLChildProperty output.
|
||||
This is just to insert a dynamically created add_new() function
|
||||
which instantiates and appends a new child object
|
||||
"""
|
||||
def __init__(self, childclass, copylist, xmlbuilder):
|
||||
list.__init__(self)
|
||||
self._childclass = childclass
|
||||
self._xmlbuilder = xmlbuilder
|
||||
for i in copylist:
|
||||
self.append(i)
|
||||
|
||||
def new(self):
|
||||
"""
|
||||
Instantiate a new child object and return it
|
||||
"""
|
||||
return self._childclass(self._xmlbuilder.conn)
|
||||
|
||||
def add_new(self):
|
||||
"""
|
||||
Instantiate a new child object, append it, and return it
|
||||
"""
|
||||
obj = self.new()
|
||||
self._xmlbuilder.add_child(obj)
|
||||
return obj
|
||||
|
||||
|
||||
class XMLChildProperty(property):
|
||||
"""
|
||||
Property that points to a class used for parsing a subsection of
|
||||
@ -305,6 +333,8 @@ class XMLChildProperty(property):
|
||||
/domain/cpu/feature of the /domain/cpu class.
|
||||
|
||||
@child_classes: Single class or list of classes to parse state into
|
||||
The list option is used by Guest._devices for parsing all
|
||||
devices into a single list
|
||||
@relative_xpath: Relative location where the class is rooted compared
|
||||
to its _XML_ROOT_PATH. So interface xml can have nested
|
||||
interfaces rooted at /interface/bridge/interface, so we pass
|
||||
@ -344,7 +374,9 @@ class XMLChildProperty(property):
|
||||
def _fget(self, xmlbuilder):
|
||||
if self.is_single:
|
||||
return self._get(xmlbuilder)
|
||||
return self._get(xmlbuilder)[:]
|
||||
return _XMLChildList(self.child_classes[0],
|
||||
self._get(xmlbuilder),
|
||||
xmlbuilder)
|
||||
|
||||
def clear(self, xmlbuilder):
|
||||
if self.is_single:
|
||||
|
@ -40,14 +40,4 @@ class XMLNSQemu(XMLBuilder):
|
||||
_XML_PROP_ORDER = ["args", "envs"]
|
||||
|
||||
args = XMLChildProperty(_XMLNSQemuArg)
|
||||
def add_arg(self, value):
|
||||
arg = _XMLNSQemuArg(conn=self.conn)
|
||||
arg.value = value
|
||||
self.add_child(arg)
|
||||
|
||||
envs = XMLChildProperty(_XMLNSQemuEnv)
|
||||
def add_env(self, name, value):
|
||||
env = _XMLNSQemuEnv(conn=self.conn)
|
||||
env.name = name
|
||||
env.value = value
|
||||
self.add_child(env)
|
||||
|
Reference in New Issue
Block a user