diff --git a/tests/xmlparse-xml/change-tpm-in.xml b/tests/xmlparse-xml/change-tpm-in.xml new file mode 100644 index 00000000..4b8af179 --- /dev/null +++ b/tests/xmlparse-xml/change-tpm-in.xml @@ -0,0 +1,63 @@ + + TestGuest + 204800 + 409600 + 12345678-1234-1234-1234-123456789012 + + hvm + + + + + + + footest + Intel + + + + + + destroy + restart + restart + 5 + + /usr/lib/xen/bin/qemu-dm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + imagelabel + + diff --git a/tests/xmlparse-xml/change-tpm-out.xml b/tests/xmlparse-xml/change-tpm-out.xml new file mode 100644 index 00000000..093e0acf --- /dev/null +++ b/tests/xmlparse-xml/change-tpm-out.xml @@ -0,0 +1,63 @@ + + TestGuest + 204800 + 409600 + 12345678-1234-1234-1234-123456789012 + + hvm + + + + + + + footest + Intel + + + + + + destroy + restart + restart + 5 + + /usr/lib/xen/bin/qemu-dm + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + imagelabel + + diff --git a/tests/xmlparse.py b/tests/xmlparse.py index 7dfea3d6..84eb090e 100644 --- a/tests/xmlparse.py +++ b/tests/xmlparse.py @@ -724,6 +724,19 @@ class XMLParseTest(unittest.TestCase): self._alter_compare(guest.get_xml_config(), outfile) + def testAlterTPM(self): + infile = "tests/xmlparse-xml/change-tpm-in.xml" + outfile = "tests/xmlparse-xml/change-tpm-out.xml" + guest = virtinst.Guest(conn=conn, + parsexml=file(infile).read()) + + dev1 = guest.get_devices("tpm")[0] + + check = self._make_checker(dev1) + check("model", "tpm-tis", "tpm-tis") + + self._alter_compare(guest.get_xml_config(), outfile) + def testConsoleCompat(self): infile = "tests/xmlparse-xml/console-compat-in.xml" outfile = "tests/xmlparse-xml/console-compat-out.xml" diff --git a/virtinst/Guest.py b/virtinst/Guest.py index 67024445..81c4b4e1 100644 --- a/virtinst/Guest.py +++ b/virtinst/Guest.py @@ -675,6 +675,7 @@ class Guest(XMLBuilderDomain.XMLBuilderDomain): "smartcard" : virtinst.VirtualSmartCardDevice, "redirdev" : virtinst.VirtualRedirDevice, "memballoon": virtinst.VirtualMemballoon, + "tpm" : virtinst.VirtualTPMDevice, } # Hand off all child element parsing to relevant classes diff --git a/virtinst/VirtualDevice.py b/virtinst/VirtualDevice.py index bbc32a61..a1e5aef6 100644 --- a/virtinst/VirtualDevice.py +++ b/virtinst/VirtualDevice.py @@ -45,6 +45,7 @@ class VirtualDevice(XMLBuilderDomain): VIRTUAL_DEV_SMARTCARD = "smartcard" VIRTUAL_DEV_REDIRDEV = "redirdev" VIRTUAL_DEV_MEMBALLOON = "memballoon" + VIRTUAL_DEV_TPM = "tpm" # Ordering in this list is important: it will be the order the # Guest class outputs XML. So changing this may upset the test suite @@ -64,7 +65,8 @@ class VirtualDevice(XMLBuilderDomain): VIRTUAL_DEV_WATCHDOG, VIRTUAL_DEV_SMARTCARD, VIRTUAL_DEV_REDIRDEV, - VIRTUAL_DEV_MEMBALLOON] + VIRTUAL_DEV_MEMBALLOON, + VIRTUAL_DEV_TPM] # General device type (disk, interface, etc.) _virtual_device_type = None diff --git a/virtinst/VirtualTPMDevice.py b/virtinst/VirtualTPMDevice.py new file mode 100644 index 00000000..c4e70fca --- /dev/null +++ b/virtinst/VirtualTPMDevice.py @@ -0,0 +1,136 @@ +# coding=utf-8 +# +# Copyright 2011 Red Hat, Inc. +# Cole Robinson +# Marc-André Lureau +# +# Copyright 2013 IBM Corporation +# Author: Stefan Berger +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301 USA. + +from virtinst.VirtualDevice import VirtualDevice +from virtinst.XMLBuilderDomain import _xml_property + + +class VirtualTPMDevice(VirtualDevice): + + _virtual_device_type = VirtualDevice.VIRTUAL_DEV_TPM + + # backend types + TPM_PASSTHROUGH = "passthrough" + + # device models + TPM_TIS = "tpm-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, caps=None): + VirtualDevice.__init__(self, conn, parsexml, parsexmlnode, caps) + + 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 = _xml_property(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 = _xml_property(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 = _xml_property(get_device_path, set_device_path, + xpath="./backend/device/@path") + + def supports_property(self, propname): + """ + Whether the TPM dev type supports the passed property name + """ + users = { + "device_path" : [self.TPM_PASSTHROUGH], + } + + if users.get(propname): + return self.type in users[propname] + + return hasattr(self, propname) + + def _get_xml_config(self): + device = "/dev/tpm0" + if self._device_path is not None: + device = self._device_path + + xml = " \n" % self.model + xml += " \n" % self.type + if self.type == "passthrough": + xml += " \n" % device + xml += " \n" + xml += " " + + return xml + + +class VirtualTPMPassthroughDevice(VirtualTPMDevice): + _tpm_type = VirtualTPMDevice.TPM_PASSTHROUGH diff --git a/virtinst/__init__.py b/virtinst/__init__.py index 5e10ca64..b608e5d9 100644 --- a/virtinst/__init__.py +++ b/virtinst/__init__.py @@ -38,6 +38,7 @@ from virtinst.VirtualFilesystem import VirtualFilesystem from virtinst.VirtualSmartCardDevice import VirtualSmartCardDevice from virtinst.VirtualRedirDevice import VirtualRedirDevice from virtinst.VirtualMemballoon import VirtualMemballoon +from virtinst.VirtualTPMDevice import VirtualTPMDevice from virtinst.DistroInstaller import DistroInstaller from virtinst.PXEInstaller import PXEInstaller from virtinst.LiveCDInstaller import LiveCDInstaller