VirtualDisk: Convert more XMLProperties to the new world order

This commit is contained in:
Cole Robinson 2013-07-13 21:04:27 -04:00
parent 41afdfd9aa
commit 5f58d05051
4 changed files with 183 additions and 203 deletions

View File

@ -23,11 +23,11 @@
<devices>
<emulator>/usr/bin/test-hv</emulator>
<disk type="file" device="disk">
<driver cache="writeback" io="threads"/>
<source file="/default-pool/UPPER"/>
<target dev="hda" bus="ide"/>
<shareable/>
<serial>WD-WMAP9A966149</serial>
<driver cache="writeback" io="threads"/>
</disk>
<disk type="file" device="disk">
<source file="/tmp/__virtinst_cli_new1.img"/>
@ -110,11 +110,11 @@
<devices>
<emulator>/usr/bin/test-hv</emulator>
<disk type="file" device="disk">
<driver cache="writeback" io="threads"/>
<source file="/default-pool/UPPER"/>
<target dev="hda" bus="ide"/>
<shareable/>
<serial>WD-WMAP9A966149</serial>
<driver cache="writeback" io="threads"/>
</disk>
<disk type="file" device="disk">
<source file="/tmp/__virtinst_cli_new1.img"/>

View File

@ -45,21 +45,21 @@ class DomainFeatures(XMLBuilder):
def set_acpi(self, val):
self._acpi = _none_or_bool(val)
acpi = XMLProperty(get_acpi, set_acpi,
xpath="./features/acpi", is_bool=True)
xpath="./features/acpi", is_tri=True)
def get_apic(self):
return self._apic
def set_apic(self, val):
self._apic = _none_or_bool(val)
apic = XMLProperty(get_apic, set_apic,
xpath="./features/apic", is_bool=True)
xpath="./features/apic", is_tri=True)
def get_pae(self):
return self._pae
def set_pae(self, val):
self._pae = _none_or_bool(val)
pae = XMLProperty(get_pae, set_pae,
xpath="./features/pae", is_bool=True)
xpath="./features/pae", is_tri=True)
def __setitem__(self, attr, val):
return setattr(self, attr, val)

View File

@ -393,13 +393,6 @@ class VirtualDisk(VirtualDevice):
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
self._device = self.DEVICE_DISK
self._readOnly = None
self._bus = None
self._shareable = None
self._driver_cache = None
self._driver_io = None
self._target = None
self._type = self._DEFAULT_SENTINEL
self._driverName = self._DEFAULT_SENTINEL
self._driverType = self._DEFAULT_SENTINEL
@ -413,6 +406,150 @@ class VirtualDisk(VirtualDevice):
self.transient = False
##########################
# Complex XML properties #
##########################
def _get_path(self):
if self._storage_creator:
return self._storage_creator.path
return self._storage_backend.path
def _set_path(self, val):
if self._storage_creator:
raise ValueError("Can't change disk path if storage creation info "
"has been set.")
if val != self.path:
self._change_storage(path=val)
def _xml_get_xpath(self):
xpath = None
ret = "./source/@file"
for prop in _TARGET_PROPS:
xpath = "./source/@" + prop
if self._xml_ctx.xpathEval(xpath):
ret = xpath
break
return ret
def _xml_set_xpath(self):
return "./source/@" + self.disk_type_to_target_prop(self.type)
path = XMLProperty(_get_path, _set_path,
xml_get_xpath=_xml_get_xpath,
xml_set_xpath=_xml_set_xpath,
clear_first=["./source/@" + target for target in
_TARGET_PROPS])
def get_type(self):
if self._type != self._DEFAULT_SENTINEL:
return self._type
return self._get_default_type()
def set_type(self, val):
if self._override_default:
self._type = val
type = XMLProperty(get_type, set_type,
xpath="./@type")
def get_device(self):
return self._device
def set_device(self, val):
if val == self._device:
return
if self._is_parse():
self.bus = None
self.target = None
self._device = val
device = XMLProperty(get_device, set_device,
xpath="./@device")
def get_driver_name(self):
if self._driverName != self._DEFAULT_SENTINEL:
return self._driverName
return self._get_default_driver()[0]
def set_driver_name(self, val):
if self._override_default:
self._driverName = val
driver_name = XMLProperty(get_driver_name, set_driver_name,
xpath="./driver/@name")
def get_driver_type(self):
if self._driverType != self._DEFAULT_SENTINEL:
return self._driverType
return self._get_default_driver()[1]
def set_driver_type(self, val):
if self._override_default:
self._driverType = val
driver_type = XMLProperty(get_driver_type, set_driver_type,
xpath="./driver/@type")
#########################
# Simple XML properties #
#########################
bus = XMLProperty(xpath="./target/@bus")
target = XMLProperty(xpath="./target/@dev")
read_only = XMLProperty(xpath="./readonly", is_bool=True)
shareable = XMLProperty(xpath="./shareable", is_bool=True)
driver_cache = XMLProperty(xpath="./driver/@cache")
driver_io = XMLProperty(xpath="./driver/@io")
error_policy = XMLProperty(xpath="./driver/@error_policy")
serial = XMLProperty(xpath="./serial")
iotune_rbs = XMLProperty(xpath="./iotune/read_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_ris = XMLProperty(xpath="./iotune/read_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_tbs = XMLProperty(xpath="./iotune/total_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_tis = XMLProperty(xpath="./iotune/total_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_wbs = XMLProperty(xpath="./iotune/write_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_wis = XMLProperty(xpath="./iotune/write_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
#############################
# Public property-esque API #
#############################
def get_sparse(self):
if self._storage_creator:
return self._storage_creator.get_sparse()
return None
def get_vol_object(self):
return self._storage_backend.get_vol_object()
def set_vol_object(self, val):
if self.path:
raise ValueError("Can't change disk vol_object if path is set.")
if self._storage_creator:
raise ValueError("Can't change disk vol_object if storage_creator "
"is set.")
if val != self.get_vol_object():
self._change_storage(vol_object=val)
def get_vol_install(self):
if not self._storage_creator:
return None
return self._storage_creator.get_vol_install()
def get_size(self):
if self._storage_creator:
return self._storage_creator.get_size()
return self._storage_backend.get_size()
#################################
# Validation assistance methods #
#################################
def set_create_storage(self, size=None, sparse=True,
fmt=None, vol_install=None, clone_path=None,
fake=False):
@ -463,169 +600,6 @@ class VirtualDisk(VirtualDevice):
if not self._storage_creator and (vol_install or clone_path):
raise RuntimeError("Need storage creation but it didn't happen.")
def _get_path(self):
if self._storage_creator:
return self._storage_creator.path
return self._storage_backend.path
def _set_path(self, val):
if self._storage_creator:
raise ValueError("Can't change disk path if storage creation info "
"has been set.")
if val != self.path:
self._change_storage(path=val)
def _xml_get_xpath(self):
xpath = None
ret = "./source/@file"
for prop in _TARGET_PROPS:
xpath = "./source/@" + prop
if self._xml_ctx.xpathEval(xpath):
ret = xpath
break
return ret
def _xml_set_xpath(self):
return "./source/@" + self.disk_type_to_target_prop(self.type)
path = XMLProperty(_get_path, _set_path,
xml_get_xpath=_xml_get_xpath,
xml_set_xpath=_xml_set_xpath,
clear_first=["./source/@" + target for target in
_TARGET_PROPS])
def get_sparse(self):
if self._storage_creator:
return self._storage_creator.get_sparse()
return None
def get_vol_object(self):
return self._storage_backend.get_vol_object()
def set_vol_object(self, val):
if self.path:
raise ValueError("Can't change disk vol_object if path is set.")
if self._storage_creator:
raise ValueError("Can't change disk vol_object if storage_creator "
"is set.")
if val != self.get_vol_object():
self._change_storage(vol_object=val)
def get_vol_install(self):
if not self._storage_creator:
return None
return self._storage_creator.get_vol_install()
def get_size(self):
if self._storage_creator:
return self._storage_creator.get_size()
return self._storage_backend.get_size()
def get_type(self):
if self._type != self._DEFAULT_SENTINEL:
return self._type
return self._get_default_type()
def set_type(self, val):
if self._override_default:
self._type = val
type = XMLProperty(get_type, set_type,
xpath="./@type")
def get_device(self):
return self._device
def set_device(self, val):
if val == self._device:
return
if self._is_parse():
self.bus = None
self.target = None
self._device = val
device = XMLProperty(get_device, set_device,
xpath="./@device")
def get_driver_name(self):
if self._driverName != self._DEFAULT_SENTINEL:
return self._driverName
return self._get_default_driver()[0]
def set_driver_name(self, val):
if self._override_default:
self._driverName = val
driver_name = XMLProperty(get_driver_name, set_driver_name,
xpath="./driver/@name")
def get_driver_type(self):
if self._driverType != self._DEFAULT_SENTINEL:
return self._driverType
return self._get_default_driver()[1]
def set_driver_type(self, val):
if self._override_default:
self._driverType = val
driver_type = XMLProperty(get_driver_type, set_driver_type,
xpath="./driver/@type")
def get_read_only(self):
return self._readOnly
def set_read_only(self, val):
self._readOnly = val
read_only = XMLProperty(get_read_only, set_read_only,
xpath="./readonly", is_bool=True)
def _get_bus(self):
return self._bus
def _set_bus(self, val):
self._bus = val
bus = XMLProperty(_get_bus, _set_bus,
xpath="./target/@bus")
def _get_target(self):
return self._target
def _set_target(self, val):
self._target = val
target = XMLProperty(_get_target, _set_target,
xpath="./target/@dev")
def _get_shareable(self):
return self._shareable
def _set_shareable(self, val):
self._shareable = val
shareable = XMLProperty(_get_shareable, _set_shareable,
xpath="./shareable", is_bool=True)
def _get_driver_cache(self):
return self._driver_cache
def _set_driver_cache(self, val):
self._driver_cache = val
driver_cache = XMLProperty(_get_driver_cache, _set_driver_cache,
xpath="./driver/@cache")
def _get_driver_io(self):
return self._driver_io
def _set_driver_io(self, val):
self._driver_io = val
driver_io = XMLProperty(_get_driver_io, _set_driver_io,
xpath="./driver/@io")
error_policy = XMLProperty(xpath="./driver/@error_policy")
serial = XMLProperty(xpath="./serial")
iotune_rbs = XMLProperty(xpath="./iotune/read_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_ris = XMLProperty(xpath="./iotune/read_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_tbs = XMLProperty(xpath="./iotune/total_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_tis = XMLProperty(xpath="./iotune/total_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_wbs = XMLProperty(xpath="./iotune/write_bytes_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
iotune_wis = XMLProperty(xpath="./iotune/write_iops_sec",
get_converter=lambda s, x: int(x or 0),
set_converter=lambda s, x: int(x))
#################################
# Validation assistance methods #
#################################
def can_be_empty(self):
return (self.device == self.DEVICE_FLOPPY or
@ -812,38 +786,31 @@ class VirtualDisk(VirtualDevice):
ret = " <disk type='%s' device='%s'>\n" % (self.type, self.device)
if path:
drvxml = ""
if self.driver_type is not None:
drvxml += " type='%s'" % self.driver_type
if self.driver_cache is not None:
drvxml += " cache='%s'" % self.driver_cache
if self.driver_io is not None:
drvxml += " io='%s'" % self.driver_io
if self.driver_name is not None:
drvxml = (" name='%s'" % self.driver_name) + drvxml
if drvxml:
ret += " <driver%s/>\n" % drvxml
drvxml = ""
if self.driver_type is not None:
drvxml += " type='%s'" % self.driver_type
if self.driver_name is not None:
drvxml = (" name='%s'" % self.driver_name) + drvxml
if drvxml:
ret += " <driver%s/>\n" % drvxml
if path is not None:
ret += " <source %s='%s'/>\n" % (typeattr, path)
bus_xml = ""
if self.bus is not None:
bus_xml = " bus='%s'" % self.bus
ret += " <target dev='%s'%s/>\n" % (self.target, bus_xml)
if self.shareable:
ret += " <shareable/>\n"
if self.read_only:
ret += " <readonly/>\n"
ret += " <target dev='%s'/>\n" % (self.target)
addr = self.indent(self.address.get_xml_config(), 6)
if addr:
ret += addr
ret += " </disk>"
return self._add_parse_bits(ret)
ret = self._add_parse_bits(ret)
# Remove <driver> block if path is None. Might not be strictly
# requires but it's what we've always done
if not self.path and "<driver" in ret:
ret = "\n".join([l for l in ret.splitlines()
if "<driver" not in l])
return ret
def is_size_conflict(self):
"""

View File

@ -225,7 +225,7 @@ class XMLProperty(property):
def __init__(self, fget=None, fset=None, doc=None,
xpath=None, get_converter=None, set_converter=None,
xml_get_xpath=None, xml_set_xpath=None,
is_bool=False, is_multi=False,
is_bool=False, is_tri=False, is_multi=False,
default_converter=None, clear_first=None):
"""
Set a XMLBuilder class property that represents a value in the
@ -254,6 +254,8 @@ class XMLProperty(property):
This allows passing functions which generate an xpath for getting
or setting.
@param is_bool: Whether this is a boolean property in the XML
@param is_tri: Boolean XML property, but return None if there's
no value set.
@param is_multi: Whether data is coming multiple or a single node
@param default_converter: If the virtinst value is "default", use
this function to get the actual XML value
@ -264,7 +266,8 @@ class XMLProperty(property):
self._xpath = xpath
self._is_bool = is_bool
self._is_tri = is_tri
self._is_bool = is_bool or is_tri
self._is_multi = is_multi
self._xpath_for_getter_cb = xml_get_xpath
@ -405,16 +408,23 @@ class XMLProperty(property):
return clear_nodes
def _convert_raw_getter(self, val):
if self._is_bool:
if self._is_tri and val is None:
return None
return bool(val)
return val
def new_getter(self, xmlbuilder, *args, **kwargs):
fgetval = self._orig_fget(xmlbuilder, *args, **kwargs)
root_node = getattr(xmlbuilder, "_xml_node")
if root_node is None:
return fgetval
return self._convert_raw_getter(fgetval)
xpath = self._xpath_for_getter(xmlbuilder)
if xpath is None:
return fgetval
return self._convert_raw_getter(fgetval)
if self._default_converter and fgetval == "default":
return fgetval
@ -520,7 +530,10 @@ class XMLBuilder(object):
def copy(self):
return copy.copy(self)
ret = copy.copy(self)
ret._propstore = ret._propstore.copy()
ret._proporder = ret._proporder[:]
return ret
def _get_conn(self):
return self._conn