VirtualTPM: Convert to new style properties

This commit is contained in:
Cole Robinson 2013-07-15 12:18:23 -04:00
parent e5a7fe6405
commit f3a37ba195
10 changed files with 48 additions and 126 deletions

View File

@ -294,7 +294,7 @@
<!-- tpm devices -->
<tpm model='tpm-tis'>
<backend type='passthrough'>
<backend path='/dev/tpm0'/>
<device path='/dev/tzz'/>
</backend>
</tpm>

View File

@ -52,7 +52,7 @@
<console type='pty'/>
<tpm model='tpm-tis'>
<backend type='passthrough'>
<backend path='/dev/tpm0'/>
<device path='/dev/tpm0'/>
</backend>
</tpm>
</devices>

View File

@ -52,7 +52,7 @@
<console type="pty"/>
<tpm model="tpm-tis">
<backend type="passthrough">
<backend path="/dev/tpm0"/>
<device path="frob"/>
</backend>
</tpm>
</devices>

View File

@ -705,7 +705,9 @@ class XMLParseTest(unittest.TestCase):
dev1 = guest.get_devices("tpm")[0]
check = self._make_checker(dev1)
check("type", "passthrough", "foo", "passthrough")
check("model", "tpm-tis", "tpm-tis")
check("device_path", "/dev/tpm0", "frob")
self._alter_compare(guest.get_xml_config(), outfile)

View File

@ -498,6 +498,9 @@ class vmmAddHardware(vmmGObjectUI):
# Video params
uihelpers.populate_video_combo(self.vm, self.widget("video-model"))
# TPM paams
self.widget("tpm-device-path").set_text("/dev/tpm0")
# Hide all notebook pages, so the wizard isn't as big as the largest
# page
notebook = self.widget("create-pages")
@ -1036,7 +1039,8 @@ class vmmAddHardware(vmmGObjectUI):
devtype = src.get_model()[src.get_active()][0]
conn = self.conn.get_backend()
self._dev = VirtualTPMDevice.get_dev_instance(conn, devtype)
self._dev = VirtualTPMDevice(conn)
self._dev.type = devtype
show_something = False
for param_name, widget_name in tpm_widget_mappings.items():
@ -1615,14 +1619,11 @@ class vmmAddHardware(vmmGObjectUI):
}
try:
self._dev = VirtualTPMDevice.get_dev_instance(conn, typ)
self._dev = VirtualTPMDevice(conn)
self._dev.type = typ
for param_name, val in value_mappings.items():
if self._dev.supports_property(param_name):
setattr(self._dev, param_name, val)
# Dump XML for sanity checking
self._dev.get_xml_config()
except Exception, e:
return self.err.val_err(_("TPM device parameter error"), e)

View File

@ -504,9 +504,6 @@ class vmmDetails(vmmGObjectUI):
"on_smartcard_mode_combo_changed": lambda *x: self.enable_apply(x,
EDIT_SMARTCARD_MODE),
"on_tpm_type_combo_changed": (self.enable_apply,
EDIT_TPM_TYPE),
"on_config_apply_clicked": self.config_apply,
"on_config_cancel_clicked": self.config_cancel,
@ -2064,8 +2061,6 @@ class vmmDetails(vmmGObjectUI):
ret = self.config_smartcard_apply(key)
elif pagetype is HW_LIST_TYPE_CONTROLLER:
ret = self.config_controller_apply(key)
elif pagetype is HW_LIST_TYPE_TPM:
ret = self.config_tpm_apply(key)
else:
ret = False
except Exception, e:
@ -2380,18 +2375,6 @@ class vmmDetails(vmmGObjectUI):
return self._change_config_helper(df, da, hf, ha)
# TPM options
def config_tpm_apply(self, dev_id_info):
df, da, add_define, hf, ha, add_hotplug = self.make_apply_data()
ignore = add_hotplug
if self.editted(EDIT_TPM_TYPE):
typ = self.get_combo_label_value("tpm-type")
if typ:
add_define(self.vm.define_tpm_type, dev_id_info, typ)
return self._change_config_helper(df, da, hf, ha)
# Network options
def config_network_apply(self, dev_id_info):
df, da, add_define, hf, ha, add_hotplug = self.make_apply_data()
@ -3239,8 +3222,8 @@ class vmmDetails(vmmGObjectUI):
self.widget(widgetname).set_text(val or "-")
dev_type = tpmdev.type
self.widget("tpm-dev-type").set_text(dev_type)
self.widget("tpm-dev-type").set_text(
virtinst.VirtualTPMDevice.get_pretty_type(dev_type))
# Device type specific properties, only show if apply to the cur dev
show_ui("device_path")

View File

@ -304,8 +304,8 @@ def populate_tpm_type_combo(vm, combo):
types.clear()
# [xml value, label]
types.append(["passthrough", "Passthrough device"])
for t in virtinst.VirtualTPMDevice.TYPES:
types.append([t, virtinst.VirtualTPMDevice.get_pretty_type(t)])
def build_netmodel_combo(vm, combo):

View File

@ -30,86 +30,26 @@ class VirtualTPMDevice(VirtualDevice):
_virtual_device_type = VirtualDevice.VIRTUAL_DEV_TPM
# backend types
TPM_PASSTHROUGH = "passthrough"
TYPE_PASSTHROUGH = "passthrough"
TYPE_DEFAULT = "default"
TYPES = [TYPE_PASSTHROUGH]
# device models
TPM_TIS = "tpm-tis"
MODEL_TIS = "tpm-tis"
MODEL_DEFAULT = "default"
MODELS = [MODEL_TIS]
# Default backend type and list of choices
TYPE_DEFAULT = TPM_PASSTHROUGH
_types = [TPM_PASSTHROUGH]
# Default device model and list of choices
MODEL_DEFAULT = TPM_TIS
_models = [TPM_TIS]
def get_dev_instance(conn, tpm_type):
"""
Set up the class attributes for the passed tpm_type
"""
if tpm_type == VirtualTPMDevice.TPM_PASSTHROUGH:
c = VirtualTPMPassthroughDevice
else:
raise ValueError(_("Unknown TPM device type '%s'.") %
tpm_type)
return c(conn, tpm_type)
get_dev_instance = staticmethod(get_dev_instance)
def __init__(self, conn, typ=TYPE_DEFAULT,
parsexml=None, parsexmlnode=None):
VirtualDevice.__init__(self, conn, parsexml, parsexmlnode)
self._type = None
self._model = self.TPM_TIS
self._device_path = None
if self._is_parse():
return
self.type = typ
def get_types(self):
return self._types[:]
types = property(get_types)
def get_type(self):
return self._type
def set_type(self, val):
if val not in self.types:
raise ValueError(_("Unknown TPM type '%s'") % val)
self._type = val
type = XMLProperty(get_type, set_type,
xpath="./backend/@type")
def get_models(self):
return self._models[:]
models = property(get_models)
def get_model(self):
return self._model
def set_model(self, val):
if val not in self.models:
raise ValueError(_("Unknown TPM model '%s'") % val)
self._model = val
model = XMLProperty(get_model, set_model,
xpath="./@model")
def get_device_path(self):
return self._device_path
def set_device_path(self, val):
self._device_path = val
device_path = XMLProperty(get_device_path, set_device_path,
xpath="./backend/device/@path")
@staticmethod
def get_pretty_type(tpm_type):
if tpm_type == VirtualTPMDevice.TYPE_PASSTHROUGH:
return _("Passthrough device")
return tpm_type
def supports_property(self, propname):
"""
Whether the TPM dev type supports the passed property name
"""
users = {
"device_path" : [self.TPM_PASSTHROUGH],
"device_path" : [self.TYPE_PASSTHROUGH],
}
if users.get(propname):
@ -117,20 +57,9 @@ class VirtualTPMDevice(VirtualDevice):
return hasattr(self, propname)
def _get_xml_config(self):
device = "/dev/tpm0"
if self._device_path is not None:
device = self._device_path
xml = " <tpm model='%s'>\n" % self.model
xml += " <backend type='%s'>\n" % self.type
if self.type == "passthrough":
xml += " <device path='%s'/>\n" % device
xml += " </backend>\n"
xml += " </tpm>"
return xml
class VirtualTPMPassthroughDevice(VirtualTPMDevice):
_tpm_type = VirtualTPMDevice.TPM_PASSTHROUGH
type = XMLProperty(xpath="./backend/@type",
default_cb=lambda s: s.TYPE_PASSTHROUGH)
model = XMLProperty(xpath="./@model",
default_cb=lambda s: s.MODEL_TIS)
device_path = XMLProperty(xpath="./backend/device/@path",
default_cb=lambda s: "/dev/tpm0")

View File

@ -1742,12 +1742,12 @@ def parse_tpm(guest, optstring, dev=None):
return None
if not dev:
dev = virtinst.VirtualTPMDevice(guest.conn, opts.get("type"))
dev = virtinst.VirtualTPMDevice(guest.conn)
set_param = _build_set_param(dev, opts)
set_param("model", "model")
set_param("type", "type")
set_param("model", "model")
set_param("path", "path")
if opts:

View File

@ -344,7 +344,7 @@ class XMLProperty(property):
Map the raw property() instance to the param name it's exposed
as in the XMLBuilder class. This is just for debug purposes.
"""
for key, val in xmlbuilder.__class__.__dict__.items():
for key, val in xmlbuilder._all_xml_props().items():
if val is self:
return key
raise RuntimeError("Didn't find expected property")
@ -703,7 +703,7 @@ class XMLBuilder(object):
Refresh the XML for the passed class propname. Used to adjust
the XML when an interdependent property changes.
"""
getattr(self.__class__, propname).refresh_xml(self)
self._all_xml_props()[propname].refresh_xml(self)
###################
@ -769,11 +769,18 @@ class XMLBuilder(object):
self._set_xml_context()
def _all_xml_props(self):
ret = {}
for c in reversed(type.mro(self.__class__)[:-1]):
for key, val in c.__dict__.items():
if val.__class__ is XMLProperty:
ret[key] = val
return ret
def _do_add_parse_bits(self, xml):
# Find all properties that have default callbacks
defaultprops = [v for v in self.__class__.__dict__.values()
if isinstance(v, XMLProperty) and
v.has_default_value()]
xmlprops = self._all_xml_props()
defaultprops = [v for v in xmlprops.values() if v.has_default_value()]
for prop in defaultprops:
prop.set_default(self)