xmlbuilder: Remove relative_xpath substitution support

This only has one user in interface.py. That case is indeed weird
but we can implement it there, rather than in generic code
This commit is contained in:
Cole Robinson 2018-03-21 10:49:29 -04:00
parent 538ea96116
commit 3e176f2aa4
2 changed files with 50 additions and 30 deletions

View File

@ -63,6 +63,18 @@ class InterfaceProtocol(XMLBuilder):
ips = XMLChildProperty(_IPAddress)
class _BondConfig(XMLBuilder):
_XML_ROOT_NAME = "bond"
class _BridgeConfig(XMLBuilder):
_XML_ROOT_NAME = "bridge"
class _VLANConfig(XMLBuilder):
_XML_ROOT_NAME = "vlan"
class Interface(XMLBuilder):
"""
Base class for building any libvirt interface object.
@ -115,24 +127,30 @@ class Interface(XMLBuilder):
"arp_target", "arp_validate_mode", "mii_frequency",
"mii_downdelay", "mii_updelay", "mii_carrier_mode",
"tag", "parent_interface",
"protocols", "interfaces"]
"protocols", "_bond", "_bridge", "_vlan"]
##################
# Child handling #
##################
######################
# Interface handling #
######################
# The recursive nature of nested interfaces complicates things here,
# which is why this is strange. See bottom of the file for more
# weirdness
_bond = XMLChildProperty(_BondConfig, is_single=True)
_bridge = XMLChildProperty(_BridgeConfig, is_single=True)
_vlan = XMLChildProperty(_VLANConfig, is_single=True)
def add_interface(self, obj):
self.add_child(obj)
getattr(self, "_" + self.type).add_child(obj)
def remove_interface(self, obj):
self.remove_child(obj)
# 'interfaces' property is added outside this class, since it needs
# to reference the completed Interface class
getattr(self, "_" + self.type).remove_child(obj)
def add_protocol(self, obj):
self.add_child(obj)
def remove_protocol(self, obj):
self.remove_child(obj)
protocols = XMLChildProperty(InterfaceProtocol)
@property
def interfaces(self):
if self.type != "ethernet":
return getattr(self, "_" + self.type).interfaces
return []
######################
@ -167,6 +185,12 @@ class Interface(XMLBuilder):
macaddr = XMLProperty("./mac/@address", validate_cb=_validate_mac)
def add_protocol(self, obj):
self.add_child(obj)
def remove_protocol(self, obj):
self.remove_child(obj)
protocols = XMLChildProperty(InterfaceProtocol)
#################
# Bridge params #
@ -241,5 +265,9 @@ class Interface(XMLBuilder):
return iface
Interface.interfaces = XMLChildProperty(Interface,
relative_xpath="./%(type)s")
# Interface can recursively have child interfaces which we can't define
# inline in the class config, hence this hackery
_BondConfig.interfaces = XMLChildProperty(Interface)
_BridgeConfig.interfaces = XMLChildProperty(Interface)
_VLANConfig.interfaces = XMLChildProperty(Interface)

View File

@ -63,14 +63,15 @@ class XMLChildProperty(property):
@child_class: XMLBuilder class this property is tracking. So for
guest.devices.disk this is DeviceDisk
@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
./bridge/interface here for example.
to its xmlbuilder root path. So if xmlbuilder is ./foo and we
want to track ./foo/bar/baz instances, set relative_xpath=./bar
@is_single: If True, this represents an XML node that is only expected
to appear once, like <domain><cpu>
"""
def __init__(self, child_class, relative_xpath=".", is_single=False):
self.child_class = child_class
self.relative_xpath = relative_xpath
self.is_single = is_single
self.relative_xpath = relative_xpath
self._propname = None
property.__init__(self, self._fget)
@ -115,17 +116,8 @@ class XMLChildProperty(property):
def set(self, xmlbuilder, obj):
xmlbuilder._propstore[self._findpropname(xmlbuilder)] = obj
def get_prop_xpath(self, xmlbuilder, obj):
relative_xpath = self.relative_xpath + "/" + obj._XML_ROOT_NAME
match = re.search("%\((.*)\)", self.relative_xpath)
if match:
valuedict = {}
for paramname in match.groups():
valuedict[paramname] = getattr(xmlbuilder, paramname)
relative_xpath = relative_xpath % valuedict
return relative_xpath
def get_prop_xpath(self, _xmlbuilder, obj):
return self.relative_xpath + "/" + obj._XML_ROOT_NAME
class XMLProperty(property):