Refactored Create New VM for more readability

This commit is contained in:
Marta Marczykowska-Górecka 2020-07-09 21:38:23 +02:00
parent f0a8241e0d
commit 2ae92dffc0
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
2 changed files with 106 additions and 64 deletions

View File

@ -41,6 +41,7 @@ class CreateVMThread(QtCore.QThread):
def __init__(self, app, vmclass, name, label, template, properties, def __init__(self, app, vmclass, name, label, template, properties,
pool): pool):
QtCore.QThread.__init__(self) QtCore.QThread.__init__(self)
print(vmclass, name, label, template, properties, pool)
self.app = app self.app = app
self.vmclass = vmclass self.vmclass = vmclass
self.name = name self.name = name
@ -100,46 +101,38 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
self.thread = None self.thread = None
self.progress = None self.progress = None
# Theoretically we should be locking for writing here and unlock utils.initialize_widget_with_labels(
# only after the VM creation finished. But the code would be widget=self.label,
# more messy... qubes_app=self.app)
# Instead we lock for writing in the actual worker thread
self.label_list, self.label_idx = utils.prepare_label_choice(
self.label,
self.app, None,
None,
allow_default=False)
self.template_list, self.template_idx = utils.prepare_vm_choice( utils.initialize_widget_with_default(
self.template_vm, widget=self.template_vm,
self.app, None, item_list=self.app.domains,
self.app.default_template, filter_function=(lambda vm: not utils.is_internal(vm) and vm.klass == 'TemplateVM'),
(lambda vm: vm.klass == 'TemplateVM'), mark_existing_as_default=True,
allow_internal=False, allow_default=True, allow_none=False) default_value=self.app.default_template)
self.netvm_list, self.netvm_idx = utils.prepare_vm_choice( utils.initialize_widget_with_default(
self.netvm, widget=self.netvm,
self.app, None, item_list=self.app.domains,
self.app.default_netvm, filter_function=(lambda vm: not utils.is_internal(vm) and vm.provides_network),
(lambda vm: vm.provides_network), add_none=True,
allow_internal=False, allow_default=True, allow_none=True) add_qubes_default=True,
default_value=self.app.default_netvm)
self.pool_list, self.pool_idx = utils.prepare_choice( utils.initialize_widget_with_default(
widget=self.storage_pool, widget=self.storage_pool,
holder=None, item_list=self.app.pools.values(),
propname=None, add_qubes_default=True,
choice=self.app.pools.values(), mark_existing_as_default=True,
default=self.app.default_pool, default_value=self.app.default_pool)
allow_default=True,
allow_none=False
)
self.name.setValidator(QtGui.QRegExpValidator( self.name.setValidator(QtGui.QRegExpValidator(
QtCore.QRegExp("[a-zA-Z0-9_-]*", QtCore.Qt.CaseInsensitive), None)) QtCore.QRegExp("[a-zA-Z0-9_-]*", QtCore.Qt.CaseInsensitive), None))
self.name.selectAll() self.name.selectAll()
self.name.setFocus() self.name.setFocus()
if not self.template_list: if self.template_vm.count() < 1:
QtWidgets.QMessageBox.warning( QtWidgets.QMessageBox.warning(
self, self,
self.tr('No template available!'), self.tr('No template available!'),
@ -147,10 +140,16 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
# Order of types is important and used elsewhere; if it's changed # Order of types is important and used elsewhere; if it's changed
# check for changes needed in self.type_change # check for changes needed in self.type_change
type_list = [self.tr("Qube based on a template (AppVM)"), type_list = [
self.tr("Standalone qube copied from a template"), (self.tr("Qube based on a template (AppVM)"), 'AppVM'),
self.tr("Empty standalone qube (install your own OS)")] (self.tr("Standalone qube copied from a template"),
self.vm_type.addItems(type_list) 'StandaloneVM-copy'),
(self.tr("Empty standalone qube (install your own OS)"),
'StandaloneVM-empty')]
utils.initialize_widget(widget=self.vm_type,
choices=type_list,
selected_value='AppVM',
add_current_label=False)
self.vm_type.currentIndexChanged.connect(self.type_change) self.vm_type.currentIndexChanged.connect(self.type_change)
@ -161,8 +160,8 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
self.done(0) self.done(0)
def accept(self): def accept(self):
vmclass = ('AppVM' if self.vm_type.currentIndex() == 0 selected_type = self.vm_type.currentData()
else 'StandaloneVM') vmclass = selected_type.split('-')[0]
name = str(self.name.text()) name = str(self.name.text())
@ -174,25 +173,21 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
'system!').format(name)) 'system!').format(name))
return return
label = self.label_list[self.label.currentIndex()] label = self.label.currentData()
if self.template_vm.currentIndex() == -1: template = self.template_vm.currentData()
template = None
else:
template = self.template_list[self.template_vm.currentIndex()]
properties = {'provides_network': self.provides_network.isChecked()} properties = {'provides_network': self.provides_network.isChecked()}
if self.netvm.currentIndex() != 0: if self.netvm.currentIndex() != 0:
properties['netvm'] = self.netvm_list[self.netvm.currentIndex()] properties['netvm'] = self.netvm.currentData()
# Standalone - not based on a template # Standalone - not based on a template
if self.vm_type.currentIndex() == 2: if selected_type == 'StandaloneVM-empty':
properties['virt_mode'] = 'hvm' properties['virt_mode'] = 'hvm'
properties['kernel'] = None properties['kernel'] = None
if self.pool_list[self.storage_pool.currentIndex()] is not \ if self.storage_pool.currentData() is not qubesadmin.DEFAULT:
qubesadmin.DEFAULT: pool = self.storage_pool.currentData()
pool = self.pool_list[self.storage_pool.currentIndex()]
else: else:
pool = None pool = None
@ -230,24 +225,21 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
['qubes-vm-boot-from-device', str(self.name.text())]) ['qubes-vm-boot-from-device', str(self.name.text())])
def type_change(self): def type_change(self):
# AppVM if self.vm_type.currentData() == 'AppVM':
if self.vm_type.currentIndex() == 0:
self.template_vm.setEnabled(True) self.template_vm.setEnabled(True)
if self.template_vm.currentIndex() == -1: if self.template_vm.currentIndex() == -1:
self.template_vm.setCurrentIndex(0) self.template_vm.setCurrentIndex(0)
self.install_system.setEnabled(False) self.install_system.setEnabled(False)
self.install_system.setChecked(False) self.install_system.setChecked(False)
# Standalone - based on a template if self.vm_type.currentData() == 'Standalone-copy':
if self.vm_type.currentIndex() == 1:
self.template_vm.setEnabled(True) self.template_vm.setEnabled(True)
if self.template_vm.currentIndex() == -1: if self.template_vm.currentIndex() == -1:
self.template_vm.setCurrentIndex(0) self.template_vm.setCurrentIndex(0)
self.install_system.setEnabled(False) self.install_system.setEnabled(False)
self.install_system.setChecked(False) self.install_system.setChecked(False)
# Standalone - not based on a template if self.vm_type.currentData() == 'Standalone-empty':
if self.vm_type.currentIndex() == 2:
self.template_vm.setEnabled(False) self.template_vm.setEnabled(False)
self.template_vm.setCurrentIndex(-1) self.template_vm.setCurrentIndex(-1)
self.install_system.setEnabled(True) self.install_system.setEnabled(True)

View File

@ -92,7 +92,7 @@ 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, selected_value=None, icon_getter=None): def initialize_widget(widget, choices, selected_value=None, icon_getter=None, add_current_label=True):
""" """
populates widget (ListBox or ComboBox) with items. Previous widget contents populates widget (ListBox or ComboBox) with items. Previous widget contents
are erased. are erased.
@ -120,13 +120,14 @@ def initialize_widget(widget, choices, selected_value=None, icon_getter=None):
widget.addItem(str(selected_value), selected_value) widget.addItem(str(selected_value), selected_value)
widget.setCurrentIndex(widget.findText(str(selected_value))) widget.setCurrentIndex(widget.findText(str(selected_value)))
widget.setItemText(widget.currentIndex(), if add_current_label:
widget.currentText() + translate(" (current)")) widget.setItemText(widget.currentIndex(),
widget.currentText() + translate(" (current)"))
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): icon_getter=None, add_current_label=True):
# 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)
@ -145,7 +146,8 @@ def initialize_widget_for_property(
initialize_widget(widget, initialize_widget(widget,
choices, choices,
selected_value=current_value, selected_value=current_value,
icon_getter=icon_getter) icon_getter=icon_getter,
add_current_label=add_current_label)
# TODO: add use icons here # TODO: add use icons here
@ -174,6 +176,44 @@ def initialize_widget_with_vms(widget,
property_name=property_name, allow_default=allow_default) property_name=property_name, allow_default=allow_default)
def initialize_widget_with_default(widget,
item_list,
filter_function=(lambda x: True),
add_none=False,
add_qubes_default=False, # refers to qubesdamin.default
mark_existing_as_default=False, # needed because the default value can be none
default_value=None):
choices = []
for item in item_list:
if not filter_function(item):
continue
if mark_existing_as_default and item == default_value:
choices.append((translate("default ({})").format(item), item))
else:
choices.append((str(item), item))
if add_qubes_default:
choices.insert(0, (translate("default ({})").format(default_value),
qubesadmin.DEFAULT))
if add_none:
if mark_existing_as_default and default_value is None:
choices.append((translate("default (none)"), None))
else:
choices.append((translate("(none)"), None))
if add_qubes_default:
selected_value = qubesadmin.DEFAULT
elif mark_existing_as_default:
selected_value = default_value
else:
selected_value = choices[0][1]
initialize_widget(
widget=widget, choices=choices, selected_value=selected_value, add_current_label=False)
def initialize_widget_with_kernels(widget, def initialize_widget_with_kernels(widget,
qubes_app, qubes_app,
allow_none=False, allow_none=False,
@ -201,13 +241,23 @@ def initialize_widget_with_labels(widget,
labels = sorted(qubes_app.labels.values(), key=lambda l: l.index) labels = sorted(qubes_app.labels.values(), key=lambda l: l.index)
choices = [(label.name, label) for label in labels] choices = [(label.name, label) for label in labels]
initialize_widget_for_property( icon_getter = (lambda label:
widget=widget, QtGui.QIcon.fromTheme(label.icon))
choices=choices,
holder=holder, if holder:
property_name=property_name, initialize_widget_for_property(
icon_getter=(lambda label: widget=widget,
QtGui.QIcon.fromTheme(label.icon))) choices=choices,
holder=holder,
property_name=property_name,
icon_getter=icon_getter)
else:
initialize_widget(widget=widget,
choices=choices,
selected_value=labels[0],
icon_getter=icon_getter,
add_current_label=False)
def prepare_choice(widget, holder, propname, choice, default, def prepare_choice(widget, holder, propname, choice, default,