Refactored VM Settings for less ugliness

This commit is contained in:
Marta Marczykowska-Górecka 2020-07-09 19:26:31 +02:00
parent ab5e3dcfea
commit f0a8241e0d
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
2 changed files with 103 additions and 105 deletions

View File

@ -153,17 +153,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.tabWidget.currentChanged.connect(self.current_tab_changed) self.tabWidget.currentChanged.connect(self.current_tab_changed)
# Initialize several auxillary variables for pylint's sake
self.netvm_idx = None
self.kernel_idx = None
self.label_idx = None
self.template_idx = None
self.root_img_size = None
self.priv_img_size = None
self.default_dispvm_idx = None
self.virt_mode_idx = None
self.virt_mode_list = None
###### basic tab ###### basic tab
self.__init_basic_tab__() self.__init_basic_tab__()
self.rename_vm_button.clicked.connect(self.rename_vm) self.rename_vm_button.clicked.connect(self.rename_vm)
@ -227,7 +216,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.warn_template_missing_apps.setVisible( self.warn_template_missing_apps.setVisible(
self.app_list_manager.has_missing) self.app_list_manager.has_missing)
def setup_application(self): def setup_application(self):
self.qapp.setApplicationName(self.tr("Qube Settings")) self.qapp.setApplicationName(self.tr("Qube Settings"))
self.qapp.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager")) self.qapp.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager"))
@ -361,9 +349,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
# netvm -> networking_groupbox # netvm -> networking_groupbox
# hvm -> include_in_balancing # hvm -> include_in_balancing
# TODO REMOVE
# other_groupbox
def __init_basic_tab__(self): def __init_basic_tab__(self):
self.vmname.setText(self.vm.name) self.vmname.setText(self.vm.name)
self.vmname.setValidator( self.vmname.setValidator(
@ -381,42 +366,41 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
if self.vm.qid == 0: if self.vm.qid == 0:
self.vmlabel.setVisible(False) self.vmlabel.setVisible(False)
else: else:
self.label_list, self.label_idx = utils.prepare_label_choice( utils.initialize_widget_with_labels(
self.vmlabel, widget=self.vmlabel,
self.vm, 'label', qubes_app=self.qubesapp,
None, holder=self.vm)
allow_default=False
)
self.vmlabel.setVisible(True) self.vmlabel.setVisible(True)
self.vmlabel.setEnabled(not self.vm.is_running()) self.vmlabel.setEnabled(not self.vm.is_running())
if self.vm.klass == 'AppVM': if self.vm.klass == 'AppVM':
self.template_list, self.template_idx = utils.prepare_vm_choice( utils.initialize_widget_with_vms(
self.template_name, widget=self.template_name,
self.vm, 'template', qubes_app=self.qubesapp,
self.vm.app.default_template, filter_function=(lambda vm: vm.klass == 'TemplateVM'),
(lambda vm: vm.klass == 'TemplateVM'), holder=self.vm,
allow_default=False, allow_none=False) property_name='template')
elif self.vm.klass == 'DispVM': elif self.vm.klass == 'DispVM':
self.template_list, self.template_idx = utils.prepare_vm_choice( utils.initialize_widget_with_vms(
self.template_name, widget=self.template_name,
self.vm, 'template', qubes_app=self.qubesapp,
self.vm.app.default_dispvm, filter_function=(lambda vm:
(lambda vm: getattr(vm, 'template_for_dispvms', False)), getattr(vm, 'template_for_dispvms', False)),
allow_default=False, allow_none=False) holder=self.vm,
property_name='template')
else: else:
self.template_name.setEnabled(False) self.template_name.setEnabled(False)
self.template_idx = -1
if self.vm.is_running(): if self.vm.is_running():
self.template_name.setEnabled(False) self.template_name.setEnabled(False)
self.netvm_list, self.netvm_idx = utils.prepare_vm_choice( utils.initialize_widget_with_vms(
self.netVM, widget=self.netVM,
self.vm, 'netvm', qubes_app=self.qubesapp,
self.vm.app.default_netvm, filter_function=(lambda vm: vm.provides_network),
(lambda vm: vm.provides_network), holder=self.vm,
allow_default=True, allow_none=True) property_name='netvm',
allow_default=True)
self.netVM.currentIndexChanged.connect(self.check_warn_dispvmnetvm) self.netVM.currentIndexChanged.connect(self.check_warn_dispvmnetvm)
@ -476,27 +460,22 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
# vm label changed # vm label changed
try: try:
if self.vmlabel.isVisible(): if self.vmlabel.isVisible():
if self.vmlabel.currentIndex() != self.label_idx: if utils.did_widget_selection_change(self.vmlabel):
label = self.label_list[self.vmlabel.currentIndex()] self.vm.label = self.vmlabel.currentData()
self.vm.label = label
self.label_idx = self.vmlabel.currentIndex()
except qubesadmin.exc.QubesException as ex: except qubesadmin.exc.QubesException as ex:
msg.append(str(ex)) msg.append(str(ex))
# vm template changed # vm template changed
try: try:
if self.template_name.currentIndex() != self.template_idx: if utils.did_widget_selection_change(self.template_name):
self.vm.template = \ self.vm.template = self.template_name.currentData()
self.template_list[self.template_name.currentIndex()]
self.template_idx = self.template_name.currentIndex()
except qubesadmin.exc.QubesException as ex: except qubesadmin.exc.QubesException as ex:
msg.append(str(ex)) msg.append(str(ex))
# vm netvm changed # vm netvm changed
try: try:
if self.netVM.currentIndex() != self.netvm_idx: if utils.did_widget_selection_change(self.netVM):
self.vm.netvm = self.netvm_list[self.netVM.currentIndex()] self.vm.netvm = self.netVM.currentData()
self.netvm_idx = self.netVM.currentIndex()
except qubesadmin.exc.QubesException as ex: except qubesadmin.exc.QubesException as ex:
msg.append(str(ex)) msg.append(str(ex))
@ -565,9 +544,8 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
if not hasattr(self.vm, 'default_dispvm'): if not hasattr(self.vm, 'default_dispvm'):
self.warn_netvm_dispvm.setVisible(False) self.warn_netvm_dispvm.setVisible(False)
return return
dispvm = self.default_dispvm_list[ dispvm = self.default_dispvm.currentData()
self.default_dispvm.currentIndex()] own_netvm = self.netVM.currentData()
own_netvm = self.netvm_list[self.netVM.currentIndex()]
if dispvm == qubesadmin.DEFAULT: if dispvm == qubesadmin.DEFAULT:
dispvm = self.vm.property_get_default('default_dispvm') dispvm = self.vm.property_get_default('default_dispvm')
@ -687,7 +665,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.progress.setModal(True) self.progress.setModal(True)
self.thread_closes = True self.thread_closes = True
self.progress.show() self.progress.show()
# TODO: maybe this can not be repeated all the time?
thread.start() thread.start()
######### advanced tab ######### advanced tab
@ -715,10 +693,13 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
# in case VM is HVM # in case VM is HVM
if hasattr(self.vm, "kernel"): if hasattr(self.vm, "kernel"):
self.kernel_groupbox.setVisible(True) self.kernel_groupbox.setVisible(True)
self.kernel_list, self.kernel_idx = utils.prepare_kernel_choice( utils.initialize_widget_with_kernels(
self.kernel, self.vm, 'kernel', widget=self.kernel,
None, qubes_app=self.qubesapp,
allow_default=True, allow_none=True) allow_none=True,
allow_default=True,
holder=self.vm,
property_name='kernel')
self.kernel.currentIndexChanged.connect(self.kernel_changed) self.kernel.currentIndexChanged.connect(self.kernel_changed)
self.kernel_opts.setText(getattr(self.vm, 'kernelopts', '-')) self.kernel_opts.setText(getattr(self.vm, 'kernelopts', '-'))
else: else:
@ -730,13 +711,16 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.other_groupbox.setVisible(False) self.other_groupbox.setVisible(False)
else: else:
self.other_groupbox.setVisible(True) self.other_groupbox.setVisible(True)
self.default_dispvm_list, self.default_dispvm_idx = \ utils.initialize_widget_with_vms(
utils.prepare_vm_choice( widget=self.default_dispvm,
self.default_dispvm, qubes_app=self.qubesapp,
self.vm, 'default_dispvm', filter_function=(lambda vm:
None, getattr(vm, 'template_for_dispvms', False)),
(lambda vm: getattr(vm, 'template_for_dispvms', False)), allow_none=True,
allow_default=True, allow_none=True) allow_default=True,
holder=self.vm,
property_name='default_dispvm'
)
self.default_dispvm.currentIndexChanged.connect( self.default_dispvm.currentIndexChanged.connect(
self.check_warn_dispvmnetvm) self.check_warn_dispvmnetvm)
@ -831,26 +815,20 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
# in case VM is not Linux # in case VM is not Linux
if hasattr(self.vm, "kernel") and self.kernel_groupbox.isVisible(): if hasattr(self.vm, "kernel") and self.kernel_groupbox.isVisible():
try: try:
if self.kernel.currentIndex() != self.kernel_idx: if utils.did_widget_selection_change(self.kernel):
self.vm.kernel = self.kernel_list[ self.vm.kernel = self.kernel.currentData()
self.kernel.currentIndex()]
self.kernel_idx = self.kernel.currentIndex()
except qubesadmin.exc.QubesException as ex: except qubesadmin.exc.QubesException as ex:
msg.append(str(ex)) msg.append(str(ex))
# vm default_dispvm changed # vm default_dispvm changed
try: try:
if self.default_dispvm.currentIndex() != self.default_dispvm_idx: if utils.did_widget_selection_change(self.default_dispvm):
self.vm.default_dispvm = \ self.vm.default_dispvm = self.default_dispvm.currentData()
self.default_dispvm_list[self.default_dispvm.currentIndex()]
self.default_dispvm_idx = self.default_dispvm.currentIndex()
except qubesadmin.exc.QubesException as ex: except qubesadmin.exc.QubesException as ex:
msg.append(str(ex)) msg.append(str(ex))
try: try:
if self.virt_mode.currentIndex() != self.virt_mode_idx: if utils.did_widget_selection_change(self.virt_mode):
self.vm.virt_mode = self.selected_virt_mode() self.vm.virt_mode = self.virt_mode.currentData()
self.virt_mode_idx = self.virt_mode.currentIndex()
except Exception as ex: # pylint: disable=broad-except except Exception as ex: # pylint: disable=broad-except
msg.append(str(ex)) msg.append(str(ex))
@ -922,22 +900,20 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.save_and_apply() self.save_and_apply()
subprocess.check_call(['qubes-vm-boot-from-device', self.vm.name]) subprocess.check_call(['qubes-vm-boot-from-device', self.vm.name])
def selected_virt_mode(self):
return self.virt_mode_list[self.virt_mode.currentIndex()]
def virt_mode_changed(self, new_idx): # pylint: disable=unused-argument def virt_mode_changed(self, new_idx): # pylint: disable=unused-argument
self.update_pv_warning() self.update_pv_warning()
self.update_pvh_dont_support_devs() self.update_pvh_dont_support_devs()
self.update_pvh_kernel_ver_warning() self.update_pvh_kernel_ver_warning()
def update_pv_warning(self): def update_pv_warning(self):
if self.selected_virt_mode() == 'PV': if self.virt_mode.currentData() == 'pv':
self.pv_warning.show() self.pv_warning.show()
else: else:
self.pv_warning.hide() self.pv_warning.hide()
def update_virt_mode_list(self): def update_virt_mode_list(self):
choices = ['HVM', 'PV'] choices = [('HVM', 'hvm'),
('PV', 'pv')]
if hasattr(self, "dev_list"): if hasattr(self, "dev_list"):
devs_attached = self.dev_list.selected_list.count() != 0 devs_attached = self.dev_list.selected_list.count() != 0
@ -947,23 +923,22 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
if devs_attached: if devs_attached:
self.pvh_mode_hidden.show() self.pvh_mode_hidden.show()
else: else:
choices.insert(0, 'PVH') choices.insert(0, ('PVH', 'pvh'))
self.pvh_mode_hidden.hide() self.pvh_mode_hidden.hide()
if self.virt_mode_list: old_mode = self.virt_mode.currentData()
old_mode = self.selected_virt_mode() if old_mode:
self.virt_mode.currentIndexChanged.disconnect() self.virt_mode.currentIndexChanged.disconnect()
else:
old_mode = None
self.virt_mode.clear() utils.initialize_widget_for_property(
widget=self.virt_mode,
self.virt_mode_list, self.virt_mode_idx = utils.prepare_choice( choices=choices,
self.virt_mode, self.vm, 'virt_mode', choices, None, holder=self.vm,
allow_default=True, transform=(lambda x: str(x).upper())) property_name='virt_mode',
allow_default=True)
if old_mode is not None: if old_mode is not None:
self.virt_mode.setCurrentIndex(self.virt_mode_list.index(old_mode)) self.virt_mode.setCurrentIndex(self.virt_mode.findData(old_mode))
self.virt_mode.currentIndexChanged.connect(self.virt_mode_changed) self.virt_mode.currentIndexChanged.connect(self.virt_mode_changed)
@ -971,11 +946,11 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.update_pvh_kernel_ver_warning() self.update_pvh_kernel_ver_warning()
def update_pvh_kernel_ver_warning(self): def update_pvh_kernel_ver_warning(self):
if self.selected_virt_mode() != 'PVH': if self.virt_mode.currentData() != 'pvh':
self.pvh_kernel_version_warning.hide() self.pvh_kernel_version_warning.hide()
return return
kernel = self.kernel_list[self.kernel.currentIndex()] kernel = self.kernel.currentData()
if self.pvh_kernel_version_ok(kernel): if self.pvh_kernel_version_ok(kernel):
self.pvh_kernel_version_warning.hide() self.pvh_kernel_version_warning.hide()
@ -1116,7 +1091,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.update_virt_mode_list() self.update_virt_mode_list()
def update_pvh_dont_support_devs(self): def update_pvh_dont_support_devs(self):
if self.selected_virt_mode() == 'PVH': if self.virt_mode.currentData() == 'pvh':
self.dev_list.setEnabled(False) self.dev_list.setEnabled(False)
self.pvh_dont_support_devs.setVisible(True) self.pvh_dont_support_devs.setVisible(True)
else: else:
@ -1156,7 +1131,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
def template_apps_change(self): def template_apps_change(self):
if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]): if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]):
self.app_list_manager.fill_apps_list( self.app_list_manager.fill_apps_list(
template=self.template_list[self.template_name.currentIndex()]) template=self.template_name.currentData())
# add a label to show # add a label to show
self.warn_template_missing_apps.setVisible( self.warn_template_missing_apps.setVisible(
self.app_list_manager.has_missing) self.app_list_manager.has_missing)

View File

@ -92,14 +92,14 @@ def did_widget_selection_change(widget):
return not translate(" (current)") in widget.currentText() return not translate(" (current)") in widget.currentText()
def initialize_widget(widget, choices, def initialize_widget(widget, choices, selected_value=None, icon_getter=None):
selected_value=None):
""" """
populates widget (ListBox or ComboBox) with items. Previous widget contents populates widget (ListBox or ComboBox) with items. Previous widget contents
are erased. are erased.
:param widget: widget to populate :param widget: widget to populate
:param choices: list of tuples (text, value) to use to populate widget :param choices: list of tuples (text, value) to use to populate widget
:param selected_value: value to populate widget with :param selected_value: value to populate widget with
:param icon_getter: function of value that returns desired icon
:return: :return:
""" """
@ -109,7 +109,10 @@ def initialize_widget(widget, choices,
for (name, value) in choices: for (name, value) in choices:
if value == selected_value: if value == selected_value:
selected_item = name selected_item = name
widget.addItem(name, value) if icon_getter is not None:
widget.addItem(icon_getter(value), name, userData=value)
else:
widget.addItem(name, userData=value)
if selected_item is not None: if selected_item is not None:
widget.setCurrentIndex(widget.findText(selected_item)) widget.setCurrentIndex(widget.findText(selected_item))
@ -122,7 +125,8 @@ def initialize_widget(widget, choices,
def initialize_widget_for_property( def initialize_widget_for_property(
widget, choices, holder, property_name, allow_default=False): widget, choices, holder, property_name, allow_default=False,
icon_getter=None):
# potentially add default # potentially add default
if allow_default: if allow_default:
default_property = holder.property_get_default(property_name) default_property = holder.property_get_default(property_name)
@ -138,9 +142,13 @@ def initialize_widget_for_property(
else: else:
current_value = getattr(holder, property_name) current_value = getattr(holder, property_name)
initialize_widget(widget, choices, selected_value=current_value) initialize_widget(widget,
choices,
selected_value=current_value,
icon_getter=icon_getter)
# TODO: add use icons here
def initialize_widget_with_vms(widget, def initialize_widget_with_vms(widget,
qubes_app, qubes_app,
filter_function=(lambda x: True), filter_function=(lambda x: True),
@ -156,7 +164,6 @@ def initialize_widget_with_vms(widget,
continue continue
if not filter_function(vm): if not filter_function(vm):
continue continue
else:
choices.append((vm.name, vm)) choices.append((vm.name, vm))
if allow_none: if allow_none:
@ -187,6 +194,22 @@ def initialize_widget_with_kernels(widget,
property_name=property_name, allow_default=allow_default) property_name=property_name, allow_default=allow_default)
def initialize_widget_with_labels(widget,
qubes_app,
holder=None,
property_name='label'):
labels = sorted(qubes_app.labels.values(), key=lambda l: l.index)
choices = [(label.name, label) for label in labels]
initialize_widget_for_property(
widget=widget,
choices=choices,
holder=holder,
property_name=property_name,
icon_getter=(lambda label:
QtGui.QIcon.fromTheme(label.icon)))
def prepare_choice(widget, holder, propname, choice, default, def prepare_choice(widget, holder, propname, choice, default,
filter_function=None, *, filter_function=None, *,
icon_getter=None, allow_internal=None, allow_default=False, icon_getter=None, allow_internal=None, allow_default=False,