virt-manager/virtManager/device/tpmdetails.py
Cole Robinson fd181cecc3 virtManager: Split out tpmdetails.py and tweak it
Split out tpmdetails.py, following the pattern of fsdetails.py. This
adds more UI editing fields for an already attached TPM.

Move the model and version under an 'Advanced options' expander,
since we should be getting this correct by default.

Signed-off-by: Cole Robinson <crobinso@redhat.com>
2022-02-19 10:02:22 -05:00

184 lines
5.3 KiB
Python

# This work is licensed under the GNU GPLv2 or later.
# See the COPYING file in the top-level directory.
from virtinst import DeviceTpm
from ..lib import uiutil
from ..baseclass import vmmGObjectUI
def _tpm_pretty_model(val):
labels = {
DeviceTpm.MODEL_TIS: _("TIS"),
DeviceTpm.MODEL_CRB: _("CRB"),
DeviceTpm.MODEL_SPAPR: _("SPAPR"),
}
return labels.get(val, val)
_EDIT_TPM_ENUM = range(1, 5)
(
_EDIT_TPM_TYPE,
_EDIT_TPM_DEVICE_PATH,
_EDIT_TPM_MODEL,
_EDIT_TPM_VERSION,
) = _EDIT_TPM_ENUM
class vmmTPMDetails(vmmGObjectUI):
__gsignals__ = {
"changed": (vmmGObjectUI.RUN_FIRST, None, []),
}
def __init__(self, vm, builder, topwin):
super().__init__("tpmdetails.ui", None,
builder=builder, topwin=topwin)
self.vm = vm
self.conn = vm.conn
self._active_edits = []
def _e(edittype):
def signal_cb(*args):
self._change_cb(edittype)
return signal_cb
self.builder.connect_signals({
"on_tpm_type_changed": _e(_EDIT_TPM_TYPE),
"on_tpm_device_path_changed": _e(_EDIT_TPM_DEVICE_PATH),
"on_tpm_model_changed": _e(_EDIT_TPM_MODEL),
"on_tpm_version_changed": _e(_EDIT_TPM_VERSION),
})
self._init_ui()
self.top_box = self.widget("top-box")
def _cleanup(self):
self.vm = None
self.conn = None
##############
# UI helpers #
##############
def _init_ui(self):
domcaps = self.vm.get_domain_capabilities()
# We could check domcaps for this, but emulated is really the
# preferred default here, so just let it fail
rows = [
[DeviceTpm.TYPE_EMULATOR, _("Emulated")],
[DeviceTpm.TYPE_PASSTHROUGH, _("Passthrough")],
]
uiutil.build_simple_combo(self.widget("tpm-type"), rows, sort=False)
rows = [[None, _("Hypervisor default")]]
if domcaps.devices.tpm.present:
values = domcaps.devices.tpm.get_enum("model").get_values()
else:
values = [DeviceTpm.MODEL_CRB, DeviceTpm.MODEL_TIS]
for v in values:
rows.append([v, _tpm_pretty_model(v)])
uiutil.build_simple_combo(self.widget("tpm-model"), rows, sort=False)
rows = [
[None, _("Hypervisor default")],
[DeviceTpm.VERSION_2_0, DeviceTpm.VERSION_2_0],
[DeviceTpm.VERSION_1_2, DeviceTpm.VERSION_1_2],
]
uiutil.build_simple_combo(self.widget("tpm-version"), rows, sort=False)
def _sync_ui(self):
devtype = uiutil.get_list_selection(self.widget("tpm-type"))
uiutil.set_grid_row_visible(self.widget("tpm-device-path"),
devtype == DeviceTpm.TYPE_PASSTHROUGH)
uiutil.set_grid_row_visible(self.widget("tpm-version"),
devtype == DeviceTpm.TYPE_EMULATOR)
##################
# Public UI APIs #
##################
def reset_state(self):
self.widget("tpm-device-path").set_text("/dev/tpm0")
uiutil.set_list_selection(
self.widget("tpm-type"), DeviceTpm.TYPE_EMULATOR)
default_model = DeviceTpm.default_model(self.vm.xmlobj)
uiutil.set_list_selection(
self.widget("tpm-model"), default_model)
uiutil.set_list_selection(
self.widget("tpm-version"), None)
def set_dev(self, dev):
self.reset_state()
uiutil.set_list_selection(
self.widget("tpm-type"), dev.type)
uiutil.set_list_selection(
self.widget("tpm-model"), dev.model)
uiutil.set_list_selection(
self.widget("tpm-version"), dev.version)
self.widget("tpm-device-path").set_text(dev.device_path or "")
self._active_edits = []
########################
# Device building APIs #
########################
def _set_values(self, dev):
typ = uiutil.get_list_selection(self.widget("tpm-type"))
model = uiutil.get_list_selection(self.widget("tpm-model"))
device_path = self.widget("tpm-device-path").get_text()
version = uiutil.get_list_selection(self.widget("tpm-version"))
if not self.widget("tpm-device-path").get_visible():
device_path = None
if not self.widget("tpm-version").get_visible():
version = None
if _EDIT_TPM_TYPE in self._active_edits:
dev.type = typ
if _EDIT_TPM_MODEL in self._active_edits:
dev.model = model
if _EDIT_TPM_DEVICE_PATH in self._active_edits:
dev.device_path = device_path
if _EDIT_TPM_VERSION in self._active_edits:
dev.version = version
return dev
def build_device(self):
self._active_edits = _EDIT_TPM_ENUM[:]
conn = self.conn.get_backend()
dev = DeviceTpm(conn)
self._set_values(dev)
dev.validate()
return dev
def update_device(self, dev):
newdev = DeviceTpm(dev.conn, parsexml=dev.get_xml())
self._set_values(newdev)
return newdev
#############
# Listeners #
#############
def _change_cb(self, edittype):
self._sync_ui()
if edittype not in self._active_edits:
self._active_edits.append(edittype)
self.emit("changed")