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