diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bf79edb7..26c4a06f 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -21,10 +21,11 @@ checks:tests:
stage: checks
variables:
PYTEST_ADDOPTS: "--color=yes"
+ BLACK_ARGS: -l88 -v --diff --color --check
before_script: &before-script
- "PATH=$PATH:$HOME/.local/bin"
- sudo dnf install -y python3-gobject python3-pytest python3-pytest-asyncio
- python3-coverage sequoia-sqv python3-pip python3-pytest-qt
+ python3-coverage sequoia-sqv python3-pip python3-pytest-qt
xorg-x11-server-Xvfb python3-PyQt6-devel python3-pyqt6
- pip3 install --quiet -r ci/requirements.txt
- git clone https://github.com/QubesOS/qubes-core-admin-client ~/core-admin-client
diff --git a/.pylintrc b/.pylintrc
index 23ee66f2..48f91cc2 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -95,7 +95,7 @@ notes=FIXME,FIX,XXX,TODO
[FORMAT]
# Maximum number of characters on a single line.
-max-line-length=80
+max-line-length=88
# Maximum number of lines in a module
max-module-lines=3000
diff --git a/qubesmanager/settings.py b/qubesmanager/settings.py
index 3db64643..481df06f 100644
--- a/qubesmanager/settings.py
+++ b/qubesmanager/settings.py
@@ -65,12 +65,8 @@
def get_default_bootmode_name(vm, bootmode):
if bootmode == "default":
- return vm.features.check_with_template(
- "boot-mode.name.default", ""
- )
- return vm.features.check_with_template(
- f"boot-mode.name.{bootmode}", bootmode
- )
+ return vm.features.check_with_template("boot-mode.name.default", "")
+ return vm.features.check_with_template(f"boot-mode.name.{bootmode}", bootmode)
# pylint: disable=too-few-public-methods
@@ -86,7 +82,7 @@ def run(self):
failed_props = []
- for (holder, prop) in self.dependencies:
+ for holder, prop in self.dependencies:
try:
if holder is None:
setattr(self.vm.app, prop, new_vm)
@@ -98,14 +94,17 @@ def run(self):
del self.vm.app.domains[self.vm.name]
else:
list_text = utils.format_dependencies_list(failed_props)
- self.msg = (self.tr("Warning: rename partially unsuccessful!"),
- self.tr("Some properties could not be changed to "
- "the new name. The system has now both {} "
- "and {} qubes. To resolve this, please "
- "check and change the following properties "
- "and remove the qube {} manually.
"
- ).format(self.vm.name, self.new_vm_name,
- self.vm.name) + list_text)
+ self.msg = (
+ self.tr("Warning: rename partially unsuccessful!"),
+ self.tr(
+ "Some properties could not be changed to "
+ "the new name. The system has now both {} "
+ "and {} qubes. To resolve this, please "
+ "check and change the following properties "
+ "and remove the qube {} manually.
"
+ ).format(self.vm.name, self.new_vm_name, self.vm.name)
+ + list_text,
+ )
except qubesadmin.exc.QubesException as ex:
self.msg = (self.tr("Rename error!"), str(ex))
@@ -121,14 +120,16 @@ def __init__(self, vm, button):
def run(self):
vms_to_refresh = [self.vm]
- template = getattr(self.vm, 'template', None)
+ template = getattr(self.vm, "template", None)
if template:
vms_to_refresh.append(template)
for vm in vms_to_refresh:
self.button.setText(
- self.tr('Refresh in progress (refreshing applications '
- 'from {})').format(vm.name))
+ self.tr("Refresh in progress (refreshing applications from {})").format(
+ vm.name
+ )
+ )
try:
if not utils.is_running(vm, True):
not_running = True
@@ -136,7 +137,7 @@ def run(self):
else:
not_running = False
- subprocess.check_call(['qvm-sync-appmenus', vm.name])
+ subprocess.check_call(["qvm-sync-appmenus", vm.name])
if not_running:
vm.shutdown()
@@ -146,19 +147,22 @@ def run(self):
# pylint: disable=too-many-instance-attributes
class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
- tabs_indices = collections.OrderedDict((
- ('basic', 0),
- ('advanced', 1),
- ('firewall', 2),
- ('devices', 3),
- ('applications', 4),
- ('services', 5),
- ('notes', 6),
- ))
+ tabs_indices = collections.OrderedDict(
+ (
+ ("basic", 0),
+ ("advanced", 1),
+ ("firewall", 2),
+ ("devices", 3),
+ ("applications", 4),
+ ("services", 5),
+ ("notes", 6),
+ )
+ )
# pylint: disable=too-many-positional-arguments
- def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
- parent=None):
+ def __init__(
+ self, vm_name, init_page="basic", qapp=None, qubesapp=None, parent=None
+ ):
super().__init__(parent)
self.vm = qubesapp.domains[vm_name]
@@ -170,17 +174,19 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
self.setupUi(self)
self.setWindowTitle(self.tr("Settings: {vm}").format(vm=self.vm.name))
- self.setWindowFlags(self.windowFlags() |
- QtCore.Qt.WindowType.WindowMaximizeButtonHint |
- QtCore.Qt.WindowType.WindowMinimizeButtonHint)
+ self.setWindowFlags(
+ self.windowFlags()
+ | QtCore.Qt.WindowType.WindowMaximizeButtonHint
+ | QtCore.Qt.WindowType.WindowMinimizeButtonHint
+ )
if init_page in self.tabs_indices:
idx = self.tabs_indices[init_page]
assert idx in range(self.tabWidget.count())
self.tabWidget.setCurrentIndex(idx)
self.buttonBox.button(
- QtWidgets.QDialogButtonBox.StandardButton.Apply).clicked.connect(
- self.apply)
+ QtWidgets.QDialogButtonBox.StandardButton.Apply
+ ).clicked.connect(self.apply)
self.tabWidget.currentChanged.connect(self.current_tab_changed)
@@ -197,15 +203,22 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
###### advanced tab
self.__init_advanced_tab__()
self.include_in_balancing.stateChanged.connect(
- self.include_in_balancing_changed)
+ self.include_in_balancing_changed
+ )
self.init_mem.editingFinished.connect(self.check_mem_changes)
self.max_mem_size.editingFinished.connect(self.check_mem_changes)
self.check_mem_changes()
+
+ self.dvm_template_checkbox.stateChanged.connect(
+ self.dvm_template_checkbox_changed
+ )
+
self.boot_from_device_button.clicked.connect(
- self.boot_from_cdrom_button_pressed)
+ self.boot_from_cdrom_button_pressed
+ )
###### firewall tab
- if self.tabWidget.isTabEnabled(self.tabs_indices['firewall']):
+ if self.tabWidget.isTabEnabled(self.tabs_indices["firewall"]):
model = firewall.QubesFirewallRulesModel()
try:
model.set_vm(self.vm)
@@ -214,23 +227,20 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
except firewall.FirewallModifiedOutsideError:
self.disable_all_fw_conf()
except qubesadmin.exc.QubesException:
- self.tabWidget.setTabEnabled(
- self.tabs_indices['firewall'], False)
+ self.tabWidget.setTabEnabled(self.tabs_indices["firewall"], False)
self.new_rule_button.clicked.connect(self.new_rule_button_pressed)
self.edit_rule_button.clicked.connect(self.edit_rule_button_pressed)
- self.delete_rule_button.clicked.connect(
- self.delete_rule_button_pressed)
+ self.delete_rule_button.clicked.connect(self.delete_rule_button_pressed)
self.policy_deny_radio_button.clicked.connect(self.policy_changed)
self.policy_allow_radio_button.clicked.connect(self.policy_changed)
- if init_page == 'firewall':
+ if init_page == "firewall":
self.check_network_availability()
####### devices tab
self.__init_devices_tab__()
self.dev_list.selectedChanged.connect(self.devices_selection_changed)
- self.no_strict_reset_button.clicked.connect(
- self.strict_reset_button_pressed)
+ self.no_strict_reset_button.clicked.connect(self.strict_reset_button_pressed)
self.current_strict_reset_list = []
self.new_strict_reset_list = []
self.define_strict_reset_devices()
@@ -245,11 +255,11 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
self.app_list = multiselectwidget.MultiSelectWidget(self)
self.app_list.change_labels(
available="All available applications",
- selected="Applications shown in App Menu")
+ selected="Applications shown in App Menu",
+ )
self.apps_layout.addWidget(self.app_list)
self.app_list_manager = AppmenuSelectManager(self.vm, self.app_list)
- self.refresh_apps_button.clicked.connect(
- self.refresh_apps_button_pressed)
+ self.refresh_apps_button.clicked.connect(self.refresh_apps_button_pressed)
# Enable Drag & Drop between between two panels
# ToDo: Disable D&D between multiple instances of qubes-vm-settings
@@ -257,22 +267,28 @@ def __init__(self, vm_name, init_page="basic", qapp=None, qubesapp=None,
self.app_list.available_list.setDragEnabled(True)
self.app_list.available_list.setAcceptDrops(True)
self.app_list.available_list.setDragDropMode(
- QtWidgets.QListWidget.DragDropMode.DragDrop)
+ QtWidgets.QListWidget.DragDropMode.DragDrop
+ )
self.app_list.available_list.setDefaultDropAction(
- QtCore.Qt.DropAction.MoveAction)
+ QtCore.Qt.DropAction.MoveAction
+ )
self.app_list.selected_list.setDragEnabled(True)
self.app_list.selected_list.setAcceptDrops(True)
self.app_list.selected_list.setDragDropMode(
- QtWidgets.QListWidget.DragDropMode.DragDrop)
+ QtWidgets.QListWidget.DragDropMode.DragDrop
+ )
self.app_list.selected_list.setDefaultDropAction(
- QtCore.Qt.DropAction.MoveAction)
+ QtCore.Qt.DropAction.MoveAction
+ )
# template change
if self.template_name.isEnabled():
self.template_name.currentIndexChanged.connect(
- self.template_apps_change)
+ self.template_apps_change
+ )
self.warn_template_missing_apps.setVisible(
- self.app_list_manager.has_missing)
+ self.app_list_manager.has_missing
+ )
####### notes tab
self.__init_notes_tab__()
@@ -290,10 +306,7 @@ def clear_threads(self):
if thread.msg:
(title, msg) = thread.msg
- QtWidgets.QMessageBox.warning(
- self,
- title,
- msg)
+ QtWidgets.QMessageBox.warning(self, title, msg)
self.threads_list.remove(thread)
@@ -302,11 +315,13 @@ def clear_threads(self):
return
- raise RuntimeError(self.tr('No finished thread found'))
+ raise RuntimeError(self.tr("No finished thread found"))
def keyPressEvent(self, event): # pylint: disable=invalid-name
- if event.key() == QtCore.Qt.Key.Key_Enter \
- or event.key() == QtCore.Qt.Key.Key_Return:
+ if (
+ event.key() == QtCore.Qt.Key.Key_Enter
+ or event.key() == QtCore.Qt.Key.Key_Return
+ ):
return
super().keyPressEvent(event)
@@ -320,9 +335,9 @@ def save_changes(self):
if error:
QtWidgets.QMessageBox.warning(
self,
- self.tr("Error while changing settings for {0}!"
- ).format(self.vm.name),
- self.tr("ERROR: {0}").format('\n'.join(error)))
+ self.tr("Error while changing settings for {0}!").format(self.vm.name),
+ self.tr("ERROR: {0}").format("\n".join(error)),
+ )
def apply(self):
self.save_changes()
@@ -362,17 +377,20 @@ def __save_changes__(self):
if ret_tmp:
ret += [self.tr("Notes tab:")] + ret_tmp
except qubesadmin.exc.QubesException as qex:
- ret.append(self.tr('Error while saving changes: ') + str(qex))
+ ret.append(self.tr("Error while saving changes: ") + str(qex))
except Exception as ex: # pylint: disable=broad-except
ret.append(repr(ex))
try:
- if self.tabWidget.isTabEnabled(self.tabs_indices['firewall']) and \
- self.policy_allow_radio_button.isEnabled():
+ if (
+ self.tabWidget.isTabEnabled(self.tabs_indices["firewall"])
+ and self.policy_allow_radio_button.isEnabled()
+ ):
self.fw_model.apply_rules(
self.policy_allow_radio_button.isChecked(),
self.temp_full_access.isChecked(),
- self.temp_full_access_time.value())
+ self.temp_full_access_time.value(),
+ )
except qubesadmin.exc.QubesException as qex:
ret += [self.tr("Firewall tab:"), str(qex)]
except Exception as ex: # pylint: disable=broad-except
@@ -386,14 +404,14 @@ def __save_changes__(self):
except Exception as ex: # pylint: disable=broad-except
ret += [self.tr("Applications tab:"), repr(ex)]
- utils.debug('\n'.join(ret))
+ utils.debug("\n".join(ret))
return ret
def check_network_availability(self):
# this should attempt to use whatever is currently selected, not VM
# settings
if self.netVM.currentData() == qubesadmin.DEFAULT:
- netvm = self.vm.property_get_default('netvm')
+ netvm = self.vm.property_get_default("netvm")
else:
netvm = self.netVM.currentData()
provides_network = self.provides_network_checkbox.isChecked()
@@ -401,9 +419,10 @@ def check_network_availability(self):
self.no_netvm_label.setVisible(netvm is None and not provides_network)
try:
- no_firewall_state = \
- netvm is not None and \
- not netvm.features.check_with_template('qubes-firewall', False)
+ no_firewall_state = (
+ netvm is not None
+ and not netvm.features.check_with_template("qubes-firewall", False)
+ )
except qubesadmin.exc.QubesDaemonAccessError:
no_firewall_state = False
@@ -412,20 +431,23 @@ def check_network_availability(self):
def collect_bootmode_data(self):
bootmode_ids = [
- x.split('.')[2] for x in self.vm.features \
- if x.startswith("boot-mode.kernelopts.")
+ x.split(".")[2]
+ for x in self.vm.features
+ if x.startswith("boot-mode.kernelopts.")
]
subject = self.vm
while hasattr(subject, "template"):
- bootmode_ids.extend([
- x.split('.')[2] for x in subject.template.features \
+ bootmode_ids.extend(
+ [
+ x.split(".")[2]
+ for x in subject.template.features
if x.startswith("boot-mode.kernelopts.")
- ])
+ ]
+ )
subject = subject.template
bootmode_names = [
- self.vm.features.check_with_template(
- f"boot-mode.name.{x}", x
- ) for x in bootmode_ids
+ self.vm.features.check_with_template(f"boot-mode.name.{x}", x)
+ for x in bootmode_ids
]
return bootmode_names, bootmode_ids
@@ -450,50 +472,56 @@ def __init_basic_tab__(self):
QtGui.QRegularExpressionValidator(
QtCore.QRegularExpression(
"[a-zA-Z0-9_-]*",
- QtCore.QRegularExpression.
- PatternOption.CaseInsensitiveOption), None))
+ QtCore.QRegularExpression.PatternOption.CaseInsensitiveOption,
+ ),
+ None,
+ )
+ )
self.vmname.setEnabled(False)
self.rename_vm_button.setEnabled(not self.vm.is_running())
self.delete_vm_button.setEnabled(not self.vm.is_running())
if utils.is_running(self.vm, False):
self.delete_vm_button.setText(
- self.tr('Delete qube (cannot delete a running qube)'))
+ self.tr("Delete qube (cannot delete a running qube)")
+ )
- if self.vm.klass == 'AdminVM':
+ if self.vm.klass == "AdminVM":
self.vmlabel.setVisible(False)
else:
try:
utils.initialize_widget_with_labels(
- widget=self.vmlabel,
- qubes_app=self.qubesapp,
- holder=self.vm)
+ widget=self.vmlabel, qubes_app=self.qubesapp, holder=self.vm
+ )
self.vmlabel.setVisible(True)
self.vmlabel.setEnabled(not utils.is_running(self.vm, False))
except qubesadmin.exc.QubesDaemonAccessError:
self.vmlabel.setEnabled(False)
- if self.vm.klass == 'AppVM':
+ if self.vm.klass == "AppVM":
try:
utils.initialize_widget_with_vms(
widget=self.template_name,
qubes_app=self.qubesapp,
- filter_function=(lambda vm: vm.klass == 'TemplateVM'),
+ filter_function=(lambda vm: vm.klass == "TemplateVM"),
holder=self.vm,
- property_name='template')
+ property_name="template",
+ )
except qubesadmin.exc.QubesDaemonAccessError:
self.template_name.setCurrentIndex(-1)
self.template_name.setEnabled(False)
- elif self.vm.klass == 'DispVM':
+ elif self.vm.klass == "DispVM":
try:
utils.initialize_widget_with_vms(
widget=self.template_name,
qubes_app=self.qubesapp,
filter_function=(
- lambda vm: getattr(vm, 'template_for_dispvms', False)),
+ lambda vm: getattr(vm, "template_for_dispvms", False)
+ ),
holder=self.vm,
- property_name='template')
+ property_name="template",
+ )
except qubesadmin.exc.QubesDaemonAccessError:
self.template_name.setCurrentIndex(-1)
self.template_name.setEnabled(False)
@@ -508,12 +536,12 @@ def __init_basic_tab__(self):
utils.initialize_widget_with_vms(
widget=self.netVM,
qubes_app=self.qubesapp,
- filter_function=(lambda vm:
- getattr(vm, 'provides_network', False)),
+ filter_function=(lambda vm: getattr(vm, "provides_network", False)),
holder=self.vm,
- property_name='netvm',
+ property_name="netvm",
allow_default=True,
- allow_none=True)
+ allow_none=True,
+ )
except qubesadmin.exc.QubesDaemonAccessError:
self.netVM.setEnabled(False)
self.netVM.setCurrentIndex(-1)
@@ -530,26 +558,32 @@ def __init_basic_tab__(self):
try:
has_shutdown_idle = self.vm.features.check_with_template(
- IDLE_SUPPORTED_SERVICE, False)
+ IDLE_SUPPORTED_SERVICE, False
+ )
if has_shutdown_idle:
self.idle_shutdown_checkbox.setChecked(
- bool(self.vm.features.get(IDLE_SERVICE, False)))
+ bool(self.vm.features.get(IDLE_SERVICE, False))
+ )
else:
text = "Shut down when idle "
- if getattr(self.vm, 'template', None):
- additional_text = "(unavailable: package " \
- "qubes-app-shutdown-idle missing " \
- "in the template)"
+ if getattr(self.vm, "template", None):
+ additional_text = (
+ "(unavailable: package "
+ "qubes-app-shutdown-idle missing "
+ "in the template)"
+ )
else:
- additional_text = "(unavailable: package " \
- "qubes-app-shutdown-idle missing " \
- "in the qube)"
+ additional_text = (
+ "(unavailable: package "
+ "qubes-app-shutdown-idle missing "
+ "in the qube)"
+ )
self.idle_shutdown_checkbox.setText(text + additional_text)
self.idle_shutdown_checkbox.setEnabled(False)
except qubesadmin.exc.QubesDaemonCommunicationError:
self.idle_shutdown_checkbox.setText(
- self.idle_shutdown_checkbox.text() +
- " (unavailable: permission denied)")
+ self.idle_shutdown_checkbox.text() + " (unavailable: permission denied)"
+ )
self.idle_shutdown_checkbox.setEnabled(False)
try:
@@ -566,46 +600,57 @@ def __init_basic_tab__(self):
# installed by rpm
self.rpm_label.setText(
- 'Yes' if getattr(self.vm, 'installed_by_rpm', False) else 'No')
+ "Yes" if getattr(self.vm, "installed_by_rpm", False) else "No"
+ )
# networking info
- if getattr(self.vm, 'netvm', None):
+ if getattr(self.vm, "netvm", None):
self.networking_groupbox.setEnabled(True)
- self.ip_label.setText(getattr(self.vm, 'ip', None) or "none")
+ self.ip_label.setText(getattr(self.vm, "ip", None) or "none")
self.netmask_label.setText(
- getattr(self.vm, 'visible_netmask', None) or "none")
+ getattr(self.vm, "visible_netmask", None) or "none"
+ )
self.gateway_label.setText(
- getattr(self.vm, 'visible_gateway', None) or "none")
- dns_list = getattr(self.vm, 'dns', '10.139.1.1 10.139.1.2')
- self.dns_label.setText(dns_list.replace(' ', ', '))
+ getattr(self.vm, "visible_gateway", None) or "none"
+ )
+ dns_list = getattr(self.vm, "dns", "10.139.1.1 10.139.1.2")
+ self.dns_label.setText(dns_list.replace(" ", ", "))
else:
self.networking_groupbox.setEnabled(False)
# max priv storage
try:
- self.priv_img_size = self.vm.volumes['private'].size // 1024**2
+ self.priv_img_size = self.vm.volumes["private"].size // 1024**2
self.max_priv_storage.setMinimum(self.priv_img_size)
self.max_priv_storage.setValue(self.priv_img_size)
self.max_priv_storage.setMaximum(
- max(self.priv_img_size,
- self.qubesapp.pools[self.vm.volumes['private'].pool].size
- // 1024**2))
+ max(
+ self.priv_img_size,
+ self.qubesapp.pools[self.vm.volumes["private"].pool].size
+ // 1024**2,
+ )
+ )
except qubesadmin.exc.QubesException:
self.max_priv_storage.setEnabled(False)
try:
- self.root_img_size = self.vm.volumes['root'].size // 1024**2
+ self.root_img_size = self.vm.volumes["root"].size // 1024**2
self.root_resize.setValue(self.root_img_size)
self.root_resize.setMinimum(self.root_img_size)
self.root_resize.setMaximum(
- max(self.root_img_size,
- self.qubesapp.pools[self.vm.volumes['root'].pool].size
- // 1024**2))
- self.root_resize.setEnabled(self.vm.volumes['root'].save_on_stop)
+ max(
+ self.root_img_size,
+ self.qubesapp.pools[self.vm.volumes["root"].pool].size // 1024**2,
+ )
+ )
+ self.root_resize.setEnabled(self.vm.volumes["root"].save_on_stop)
if not self.root_resize.isEnabled():
self.root_resize.setToolTip(
- self.tr("To change system storage size, change properties "
- "of the underlying template."))
+ self.tr(
+ "To change system storage size, change properties "
+ "of the underlying template."
+ )
+ )
self.root_resize_label.setEnabled(self.root_resize.isEnabled())
except qubesadmin.exc.QubesException:
self.root_resize.setEnabled(False)
@@ -632,19 +677,26 @@ def __apply_basic_tab__(self):
try:
if utils.did_widget_selection_change(self.netVM):
if self.netVM.currentData() == qubesadmin.DEFAULT:
- netvm = self.vm.property_get_default('netvm')
+ netvm = self.vm.property_get_default("netvm")
else:
netvm = self.netVM.currentData()
- if self.vm.get_power_state() == 'Running' and netvm and \
- netvm.get_power_state() != 'Running':
+ if (
+ self.vm.get_power_state() == "Running"
+ and netvm
+ and netvm.get_power_state() != "Running"
+ ):
reply = QtWidgets.QMessageBox.question(
- self, self.tr("Qube Start Confirmation"),
- self.tr("
Can not change netvm of a running qube"
- "to a halted Qube.
"
- "Do you want to start the Qube"
- " '{0}'?").format(netvm.name),
- QtWidgets.QMessageBox.StandardButton.Yes |
- QtWidgets.QMessageBox.StandardButton.Cancel)
+ self,
+ self.tr("Qube Start Confirmation"),
+ self.tr(
+ "
Can not change netvm of a running qube"
+ "to a halted Qube.
"
+ "Do you want to start the Qube"
+ " '{0}'?"
+ ).format(netvm.name),
+ QtWidgets.QMessageBox.StandardButton.Yes
+ | QtWidgets.QMessageBox.StandardButton.Cancel,
+ )
if reply == QtWidgets.QMessageBox.StandardButton.Yes:
netvm.start()
@@ -656,9 +708,10 @@ def __apply_basic_tab__(self):
# include in backups
try:
- if self.include_in_backups.isEnabled() and\
- self.vm.include_in_backups != \
- self.include_in_backups.isChecked():
+ if (
+ self.include_in_backups.isEnabled()
+ and self.vm.include_in_backups != self.include_in_backups.isChecked()
+ ):
self.vm.include_in_backups = self.include_in_backups.isChecked()
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -674,10 +727,11 @@ def __apply_basic_tab__(self):
# shutdown-idle
try:
current_idle = self.vm.features.get(IDLE_SERVICE, False)
- if self.idle_shutdown_checkbox.isEnabled() and \
- self.idle_shutdown_checkbox.isChecked() != current_idle:
- self.vm.features[IDLE_SERVICE] = \
- self.idle_shutdown_checkbox.isChecked()
+ if (
+ self.idle_shutdown_checkbox.isEnabled()
+ and self.idle_shutdown_checkbox.isChecked() != current_idle
+ ):
+ self.vm.features[IDLE_SERVICE] = self.idle_shutdown_checkbox.isChecked()
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -686,7 +740,7 @@ def __apply_basic_tab__(self):
priv_size = self.max_priv_storage.value()
if self.priv_img_size != priv_size:
try:
- self.vm.volumes['private'].resize(priv_size * 1024**2)
+ self.vm.volumes["private"].resize(priv_size * 1024**2)
self.priv_img_size = priv_size
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -696,7 +750,7 @@ def __apply_basic_tab__(self):
sys_size = self.root_resize.value()
if self.root_img_size != sys_size:
try:
- self.vm.volumes['root'].resize(sys_size * 1024**2)
+ self.vm.volumes["root"].resize(sys_size * 1024**2)
self.root_img_size = sys_size
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -716,24 +770,25 @@ def check_mem_changes(self):
QtWidgets.QMessageBox.warning(
self,
self.tr("Warning!"),
- self.tr("Max memory can not be less than initial memory.
"
- "Setting max memory to equal initial memory."))
+ self.tr(
+ "Max memory can not be less than initial memory.
"
+ "Setting max memory to equal initial memory."
+ ),
+ )
self.max_mem_size.setValue(self.init_mem.value())
# Linux specific limit: init memory must not be below
# max_mem_size/10.79 in order to allow scaling up to
# max_mem_size (or else "add_memory() failed: -17" problem)
try:
- is_linux = self.vm.features.check_with_template('os', None) == \
- 'Linux'
+ is_linux = self.vm.features.check_with_template("os", None) == "Linux"
except qubesadmin.exc.QubesException:
is_linux = False
- if is_linux and \
- self.init_mem.value() * 10 < self.max_mem_size.value():
+ if is_linux and self.init_mem.value() * 10 < self.max_mem_size.value():
self.warn_too_much_mem_label.setVisible(True)
def check_warn_templatenetvm(self):
- if self.vm.klass != 'TemplateVM':
+ if self.vm.klass != "TemplateVM":
return
current_netvm = self.netVM.currentData()
@@ -748,10 +803,12 @@ def check_warn_templatenetvm(self):
"Connecting a TemplateVM directly to a network is highly"
" discouraged!
You are breaking a basic part "
"of Qubes security and there is probably no real need"
- " to do so. Continue at your own risk."))
+ " to do so. Continue at your own risk."
+ ),
+ )
def check_warn_dispvmnetvm(self):
- if not hasattr(self.vm, 'default_dispvm'):
+ if not hasattr(self.vm, "default_dispvm"):
self.warn_netvm_dispvm.setVisible(False)
return
dispvm = self.default_dispvm.currentData()
@@ -759,7 +816,7 @@ def check_warn_dispvmnetvm(self):
if dispvm == qubesadmin.DEFAULT:
try:
- dispvm = self.vm.property_get_default('default_dispvm')
+ dispvm = self.vm.property_get_default("default_dispvm")
except qubesadmin.exc.QubesDaemonAccessError:
pass
@@ -767,11 +824,11 @@ def check_warn_dispvmnetvm(self):
self.warn_netvm_dispvm.setVisible(False)
return
- dispvm_netvm = getattr(dispvm, 'netvm', None)
+ dispvm_netvm = getattr(dispvm, "netvm", None)
if own_netvm == qubesadmin.DEFAULT:
try:
- own_netvm = self.vm.property_get_default('netvm')
+ own_netvm = self.vm.property_get_default("netvm")
except qubesadmin.exc.QubesDaemonAccessError:
# no point in warning if we don't know what we're warning about
self.warn_netvm_dispvm.setVisible(False)
@@ -783,7 +840,7 @@ def check_warn_dispvmnetvm(self):
self.warn_netvm_dispvm.setVisible(False)
def check_warn_anonnetvm(self):
- if 'anon-vm' not in self.vm.tags:
+ if "anon-vm" not in self.vm.tags:
return
current_net_vm = self.netVM.currentData()
@@ -792,9 +849,9 @@ def check_warn_anonnetvm(self):
return
if current_net_vm == qubesadmin.DEFAULT:
- current_net_vm = self.vm.property_get_default('netvm')
+ current_net_vm = self.vm.property_get_default("netvm")
- if 'anon-gateway' not in current_net_vm.tags:
+ if "anon-gateway" not in current_net_vm.tags:
QtWidgets.QMessageBox.warning(
self,
self.tr("Warning!"),
@@ -803,16 +860,19 @@ def check_warn_anonnetvm(self):
"to ensure privacy and anonymity. By changing the net qube "
"to a gateway that does not provide anonymity, your IP "
"address will be leaked on the Internet. Continue at your "
- "own risk.")
+ "own risk."
+ ),
)
def rename_vm(self):
dependencies = admin_utils.vm_dependencies(self.vm.app, self.vm)
- running_dependencies = [vm.name for (vm, prop) in dependencies
- if vm and prop == 'template'
- and utils.is_running(vm, False)]
+ running_dependencies = [
+ vm.name
+ for (vm, prop) in dependencies
+ if vm and prop == "template" and utils.is_running(vm, False)
+ ]
if running_dependencies:
QtWidgets.QMessageBox.warning(
@@ -821,15 +881,17 @@ def rename_vm(self):
self.tr(
"The following qubes using this qube as a template are "
"running:
{}.
In order to rename this qube, you "
- "must first shut them down.").format(
- ", ".join(running_dependencies)))
+ "must first shut them down."
+ ).format(", ".join(running_dependencies)),
+ )
return
new_vm_name, ok = QtWidgets.QInputDialog.getText(
self,
- self.tr('Rename qube'),
- self.tr('New name: (WARNING: all other changes will be discarded)'),
- text=self.vm.name)
+ self.tr("Rename qube"),
+ self.tr("New name: (WARNING: all other changes will be discarded)"),
+ text=self.vm.name,
+ )
if ok:
thread = RenameVMThread(self.vm, new_vm_name, dependencies)
@@ -837,7 +899,8 @@ def rename_vm(self):
thread.finished.connect(self.clear_threads)
self.progress = QtWidgets.QProgressDialog(
- self.tr("Renaming Qube..."), "", 0, 0)
+ self.tr("Renaming Qube..."), "", 0, 0
+ )
self.progress.setCancelButton(None)
self.progress.setModal(True)
self.thread_closes = True
@@ -854,20 +917,26 @@ def remove_vm(self):
QtWidgets.QMessageBox.warning(
self,
self.tr("Qube cannot be removed!"),
- self.tr("This qube cannot be removed. It is used as:"
- "
{} If you want to remove this qube, "
- "you should remove or change settings of each qube "
- "or setting that uses it.").format(list_text))
+ self.tr(
+ "This qube cannot be removed. It is used as:"
+ "
{} If you want to remove this qube, "
+ "you should remove or change settings of each qube "
+ "or setting that uses it."
+ ).format(list_text),
+ )
return
answer, ok = QtWidgets.QInputDialog.getText(
self,
- self.tr('Delete qube'),
- self.tr('Are you absolutely sure you want to delete this qube? '
- '
All qube settings and data will be irrevocably'
- ' deleted.
If you are sure, please enter this '
- 'qube\'s name below.'))
+ self.tr("Delete qube"),
+ self.tr(
+ "Are you absolutely sure you want to delete this qube? "
+ "
All qube settings and data will be irrevocably"
+ " deleted.
If you are sure, please enter this "
+ "qube's name below."
+ ),
+ )
if ok and answer == self.vm.name:
thread = common_threads.RemoveVMThread(self.vm)
@@ -875,7 +944,8 @@ def remove_vm(self):
self.threads_list.append(thread)
self.progress = QtWidgets.QProgressDialog(
- self.tr("Deleting Qube..."), "", 0, 0)
+ self.tr("Deleting Qube..."), "", 0, 0
+ )
self.progress.setCancelButton(None)
self.progress.setModal(True)
self.thread_closes = True
@@ -887,20 +957,20 @@ def remove_vm(self):
QtWidgets.QMessageBox.warning(
self,
self.tr("Removal cancelled"),
- self.tr("The qube will not be removed."))
+ self.tr("The qube will not be removed."),
+ )
def clone_vm(self):
with common_threads.busy_cursor():
- clone_window = clone_vm.CloneVMDlg(
- self.qapp, self.qubesapp, src_vm=self.vm)
+ clone_window = clone_vm.CloneVMDlg(self.qapp, self.qubesapp, src_vm=self.vm)
clone_window.exec()
######### advanced tab
- def __init_advanced_tab__(self):
+ def __init_advanced_tab__(self): # pylint: disable=too-many-statements
- vm_memory = getattr(self.vm, 'memory', None)
- vm_maxmem = getattr(self.vm, 'maxmem', None)
+ vm_memory = getattr(self.vm, "memory", None)
+ vm_maxmem = getattr(self.vm, "maxmem", None)
if vm_memory is None:
self.init_mem.setEnabled(False)
@@ -913,21 +983,20 @@ def __init_advanced_tab__(self):
self.max_mem_size.setValue(int(vm_maxmem))
else:
try:
- maxmem = self.vm.property_get_default('maxmem')
+ maxmem = self.vm.property_get_default("maxmem")
except qubesadmin.exc.QubesDaemonAccessError:
maxmem = 0
if maxmem == 0:
maxmem = vm_memory
self.max_mem_size.setValue(
- int(utils.get_feature(
- self.vm, 'qubesmanager.maxmem_value', maxmem)))
+ int(utils.get_feature(self.vm, "qubesmanager.maxmem_value", maxmem))
+ )
self.vcpus.setMinimum(1)
- self.vcpus.setValue(int(getattr(self.vm, 'vcpus', 1)))
+ self.vcpus.setValue(int(getattr(self.vm, "vcpus", 1)))
self.include_in_balancing.setEnabled(True)
- self.include_in_balancing.setChecked(
- int(getattr(self.vm, 'maxmem', 0)) > 0)
+ self.include_in_balancing.setChecked(int(getattr(self.vm, "maxmem", 0)) > 0)
self.max_mem_size.setEnabled(self.include_in_balancing.isChecked())
# in case VM is HVM
@@ -940,9 +1009,10 @@ def __init_advanced_tab__(self):
allow_none=True,
allow_default=True,
holder=self.vm,
- property_name='kernel')
+ property_name="kernel",
+ )
self.kernel.currentIndexChanged.connect(self.kernel_changed)
- self.kernel_opts.setText(getattr(self.vm, 'kernelopts', '-'))
+ self.kernel_opts.setText(getattr(self.vm, "kernelopts", "-"))
# load bootmode information from features
if hasattr(self.vm, "appvm_default_bootmode"):
self.appvm_default_bootmode_desc.setVisible(True)
@@ -950,11 +1020,8 @@ def __init_advanced_tab__(self):
else:
self.appvm_default_bootmode_desc.setVisible(False)
self.appvm_default_bootmode.setVisible(False)
- self.bootmode_names, self.bootmode_ids \
- = self.collect_bootmode_data()
- bootmode_widget_data = list(zip(
- self.bootmode_names, self.bootmode_ids
- ))
+ self.bootmode_names, self.bootmode_ids = self.collect_bootmode_data()
+ bootmode_widget_data = list(zip(self.bootmode_names, self.bootmode_ids))
bootmode_widget_data.sort()
utils.initialize_widget_for_property(
widget=self.bootmode,
@@ -962,7 +1029,7 @@ def __init_advanced_tab__(self):
property_name="bootmode",
holder=self.vm,
allow_default=True,
- default_text_provider=get_default_bootmode_name
+ default_text_provider=get_default_bootmode_name,
)
if hasattr(self.vm, "appvm_default_bootmode"):
utils.initialize_widget_for_property(
@@ -971,13 +1038,12 @@ def __init_advanced_tab__(self):
property_name="appvm_default_bootmode",
holder=self.vm,
allow_default=True,
- default_text_provider=get_default_bootmode_name
+ default_text_provider=get_default_bootmode_name,
)
if self.vm.bootmode != "default":
self.bootmode_kernel_opts.setText(
self.vm.features.check_with_template(
- f"boot-mode.kernelopts.{self.vm.bootmode}",
- ""
+ f"boot-mode.kernelopts.{self.vm.bootmode}", ""
)
)
else:
@@ -990,7 +1056,7 @@ def __init_advanced_tab__(self):
self.kernel.setEnabled(False)
self.kernel_groupbox.setVisible(False)
- if not hasattr(self.vm, 'default_dispvm'):
+ if not hasattr(self.vm, "default_dispvm"):
self.other_groupbox.setVisible(False)
else:
try:
@@ -998,16 +1064,17 @@ def __init_advanced_tab__(self):
utils.initialize_widget_with_vms(
widget=self.default_dispvm,
qubes_app=self.qubesapp,
- filter_function=(lambda vm:
- getattr(
- vm, 'template_for_dispvms', False)),
+ filter_function=(
+ lambda vm: getattr(vm, "template_for_dispvms", False)
+ ),
allow_none=True,
allow_default=True,
holder=self.vm,
- property_name='default_dispvm'
+ property_name="default_dispvm",
)
self.default_dispvm.currentIndexChanged.connect(
- self.check_warn_dispvmnetvm)
+ self.check_warn_dispvmnetvm
+ )
except qubesadmin.exc.QubesDaemonAccessError:
self.other_groupbox.setVisible(False)
@@ -1015,9 +1082,10 @@ def __init_advanced_tab__(self):
self.update_virt_mode_list()
try:
- windows_running = \
- self.vm.features.check_with_template('os', None) == 'Windows' \
+ windows_running = (
+ self.vm.features.check_with_template("os", None) == "Windows"
and self.vm.is_running()
+ )
except qubesadmin.exc.QubesException:
windows_running = False
@@ -1028,22 +1096,43 @@ def __init_advanced_tab__(self):
self.seamless_off_button.clicked.connect(self.disable_seamless)
self.dvm_template_checkbox.setChecked(
- getattr(self.vm, 'template_for_dispvms', False))
+ getattr(self.vm, "template_for_dispvms", False)
+ )
- if not hasattr(self.vm, 'template_for_dispvms'):
+ if not hasattr(self.vm, "template_for_dispvms"):
self.dvm_template_checkbox.setEnabled(False)
+ self.preload_dispvm.setMinimum(0)
+ self.preload_dispvm.setMaximum(50)
+ if (
+ self.vm.name == getattr(self.vm.app, "default_dispvm", None)
+ and self.vm.app.domains["dom0"].features.get("preload-dispvm-max", None)
+ is not None
+ ):
+ self.warn_default_dispvm_preload_label.setVisible(True)
+ else:
+ self.warn_default_dispvm_preload_label.setVisible(False)
+ self.preload_dispvm.setEnabled(self.dvm_template_checkbox.isChecked())
+ if self.preload_dispvm.isEnabled():
+ vm_preload_dispvm = int(self.vm.features.get("preload-dispvm-max") or 0)
+ else:
+ vm_preload_dispvm = 0
+ self.preload_dispvm.setValue(vm_preload_dispvm)
+
self.provides_network_checkbox.setChecked(
- getattr(self.vm, 'provides_network', False))
+ getattr(self.vm, "provides_network", False)
+ )
if self.provides_network_checkbox.isChecked():
- domains_using = [vm.name for vm
- in getattr(self.vm, 'connected_vms', [])]
+ domains_using = [vm.name for vm in getattr(self.vm, "connected_vms", [])]
if domains_using:
self.provides_network_checkbox.setEnabled(False)
- self.provides_network_checkbox.setToolTip(self.tr(
- "Cannot change this setting while this qube is used as a "
- "NetVM by the following qubes:\n") +
- "\n".join(domains_using))
+ self.provides_network_checkbox.setToolTip(
+ self.tr(
+ "Cannot change this setting while this qube is used as "
+ "a NetVM by the following qubes:\n"
+ )
+ + "\n".join(domains_using)
+ )
try:
self.run_in_debug_mode.setChecked(self.vm.debug)
@@ -1060,29 +1149,27 @@ def __init_advanced_tab__(self):
self.prohibit_start_rationale_edited
)
self.prohibit_start_checkbox.setChecked(bool(rationale))
- self.prohibit_start_checkbox.clicked.connect(
- self.prohibit_start_checked
- )
+ self.prohibit_start_checkbox.clicked.connect(self.prohibit_start_checked)
utils.initialize_widget(
widget=self.allow_fullscreen,
choices=[
- ('(use system default)', None),
- ('allow', True),
- ('disallow', False)
+ ("(use system default)", None),
+ ("allow", True),
+ ("disallow", False),
],
- selected_value=utils.get_boolean_feature(self.vm,
- 'gui-allow-fullscreen'))
+ selected_value=utils.get_boolean_feature(self.vm, "gui-allow-fullscreen"),
+ )
self.allow_fullscreen_initial = self.allow_fullscreen.currentIndex()
utils.initialize_widget(
widget=self.allow_utf8,
choices=[
- ('(use system default)', None),
- ('allow', True),
- ('disallow', False)
+ ("(use system default)", None),
+ ("allow", True),
+ ("disallow", False),
],
- selected_value=utils.get_boolean_feature(self.vm,
- 'gui-allow-utf8-titles'))
+ selected_value=utils.get_boolean_feature(self.vm, "gui-allow-utf8-titles"),
+ )
self.allow_utf8_initial = self.allow_utf8.currentIndex()
def prohibit_start_checked(self, status):
@@ -1097,35 +1184,41 @@ def prohibit_start_rationale_edited(self, text):
def enable_seamless(self):
try:
- self.vm.run_service_for_stdio("qubes.SetGuiMode", input=b'SEAMLESS')
- except (qubesadmin.exc.QubesException,
- subprocess.CalledProcessError) as ex:
+ self.vm.run_service_for_stdio("qubes.SetGuiMode", input=b"SEAMLESS")
+ except (
+ qubesadmin.exc.QubesException,
+ subprocess.CalledProcessError,
+ ) as ex:
QtWidgets.QMessageBox.warning(
self,
self.tr("Failed to set seamless mode"),
- self.tr("Error occurred: {}".format(str(ex))))
+ self.tr("Error occurred: {}".format(str(ex))),
+ )
def disable_seamless(self):
try:
- self.vm.run_service_for_stdio("qubes.SetGuiMode",
- input=b'FULLSCREEN')
- except (qubesadmin.exc.QubesException,
- subprocess.CalledProcessError) as ex:
+ self.vm.run_service_for_stdio("qubes.SetGuiMode", input=b"FULLSCREEN")
+ except (
+ qubesadmin.exc.QubesException,
+ subprocess.CalledProcessError,
+ ) as ex:
QtWidgets.QMessageBox.warning(
self,
self.tr("Failed to set fullscreen mode"),
- self.tr("Error occurred: {}".format(str(ex))))
+ self.tr("Error occurred: {}".format(str(ex))),
+ )
def __apply_advanced_tab__(self):
msg = []
# mem/cpu
try:
- if self.init_mem.isEnabled() and \
- self.init_mem.value() != int(self.vm.memory):
+ if self.init_mem.isEnabled() and self.init_mem.value() != int(
+ self.vm.memory
+ ):
self.vm.memory = self.init_mem.value()
- curr_maxmem = int(getattr(self.vm, 'maxmem', 0))
+ curr_maxmem = int(getattr(self.vm, "maxmem", 0))
if not self.include_in_balancing.isChecked():
maxmem = 0
@@ -1134,14 +1227,24 @@ def __apply_advanced_tab__(self):
if maxmem != curr_maxmem:
if curr_maxmem > 0:
- self.vm.features['qubesmanager.maxmem_value'] = curr_maxmem
+ self.vm.features["qubesmanager.maxmem_value"] = curr_maxmem
if maxmem == 0 or self.max_mem_size.isEnabled():
self.vm.maxmem = maxmem
- if self.vcpus.isEnabled() and \
- self.vcpus.value() != int(self.vm.vcpus):
+ if self.vcpus.isEnabled() and self.vcpus.value() != int(self.vm.vcpus):
self.vm.vcpus = self.vcpus.value()
+ if (
+ self.dvm_template_checkbox.isChecked()
+ and self.preload_dispvm.isEnabled()
+ ):
+ curr_preload_dispvm = (
+ int(self.vm.features.get("preload-dispvm-max") or 0)
+ )
+ preload_dispvm = self.preload_dispvm.value()
+ if preload_dispvm != curr_preload_dispvm:
+ self.vm.features["preload-dispvm-max"] = preload_dispvm
+
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -1153,10 +1256,10 @@ def __apply_advanced_tab__(self):
if utils.did_widget_selection_change(self.bootmode):
self.vm.bootmode = self.bootmode.currentData()
if hasattr(self.vm, "appvm_default_bootmode"):
- if utils.did_widget_selection_change(
- self.appvm_default_bootmode):
- self.vm.appvm_default_bootmode \
- = self.appvm_default_bootmode.currentData()
+ if utils.did_widget_selection_change(self.appvm_default_bootmode):
+ self.vm.appvm_default_bootmode = (
+ self.appvm_default_bootmode.currentData()
+ )
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -1172,11 +1275,12 @@ def __apply_advanced_tab__(self):
except Exception as ex: # pylint: disable=broad-except
msg.append(str(ex))
- if getattr(self.vm, "template_for_dispvms", False) != \
- self.dvm_template_checkbox.isChecked():
+ if (
+ getattr(self.vm, "template_for_dispvms", False)
+ != self.dvm_template_checkbox.isChecked()
+ ):
try:
- self.vm.template_for_dispvms = \
- self.dvm_template_checkbox.isChecked()
+ self.vm.template_for_dispvms = self.dvm_template_checkbox.isChecked()
if self.dvm_template_checkbox.isChecked():
self.vm.features["appmenus-dispvm"] = True
else:
@@ -1184,11 +1288,12 @@ def __apply_advanced_tab__(self):
except Exception as ex: # pylint: disable=broad-except
msg.append(str(ex))
- if getattr(self.vm, 'provides_network', False) != \
- self.provides_network_checkbox.isChecked():
+ if (
+ getattr(self.vm, "provides_network", False)
+ != self.provides_network_checkbox.isChecked()
+ ):
try:
- self.vm.provides_network = \
- self.provides_network_checkbox.isChecked()
+ self.vm.provides_network = self.provides_network_checkbox.isChecked()
except Exception as ex: # pylint: disable=broad-except
msg.append(str(ex))
@@ -1202,8 +1307,7 @@ def __apply_advanced_tab__(self):
rationale = self.vm.features.get("prohibit-start", "")
if (self.prohibit_start_checkbox.isChecked() != bool(rationale)) or (
- bool(rationale)
- and self.prohibit_start_rationale.text() != rationale
+ bool(rationale) and self.prohibit_start_rationale.text() != rationale
):
rationale = self.prohibit_start_rationale.text()
if bool(rationale) and self.prohibit_start_checkbox.isChecked():
@@ -1211,25 +1315,25 @@ def __apply_advanced_tab__(self):
else:
del self.vm.features["prohibit-start"]
- if self.allow_fullscreen_initial !=\
- self.allow_fullscreen.currentIndex():
+ if self.allow_fullscreen_initial != self.allow_fullscreen.currentIndex():
try:
if self.allow_fullscreen.currentData() is None:
- del self.vm.features['gui-allow-fullscreen']
+ del self.vm.features["gui-allow-fullscreen"]
else:
- self.vm.features['gui-allow-fullscreen'] = \
+ self.vm.features["gui-allow-fullscreen"] = (
self.allow_fullscreen.currentData()
+ )
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
- if self.allow_utf8_initial !=\
- self.allow_utf8.currentIndex():
+ if self.allow_utf8_initial != self.allow_utf8.currentIndex():
try:
if self.allow_utf8.currentData() is None:
- del self.vm.features['gui-allow-utf8-titles']
+ del self.vm.features["gui-allow-utf8-titles"]
else:
- self.vm.features['gui-allow-utf8-titles'] = \
+ self.vm.features["gui-allow-utf8-titles"] = (
self.allow_utf8.currentData()
+ )
except qubesadmin.exc.QubesException as ex:
msg.append(str(ex))
@@ -1247,14 +1351,16 @@ def include_in_balancing_changed(self, state):
if self.include_in_balancing.isChecked():
self.check_mem_changes()
+ def dvm_template_checkbox_changed(self, state): # pylint: disable=unused-argument
+ self.preload_dispvm.setEnabled(self.dvm_template_checkbox.isChecked())
+
def boot_from_cdrom_button_pressed(self):
boot_dialog = bootfromdevice.VMBootFromDeviceWindow(
- vm=self.vm.name, qapp=self.qapp, qubesapp=self.qubesapp,
- parent=self)
+ vm=self.vm.name, qapp=self.qapp, qubesapp=self.qubesapp, parent=self
+ )
if boot_dialog.exec():
self.save_and_apply()
- qvm_start.main(
- ['--cdrom', boot_dialog.cdrom_location, self.vm.name])
+ qvm_start.main(["--cdrom", boot_dialog.cdrom_location, self.vm.name])
def virt_mode_changed(self, new_idx): # pylint: disable=unused-argument
self.update_pv_warning()
@@ -1262,22 +1368,22 @@ def virt_mode_changed(self, new_idx): # pylint: disable=unused-argument
self.update_pvh_kernel_ver_warning()
def update_pv_warning(self):
- if self.virt_mode.currentData() == 'pv':
+ if self.virt_mode.currentData() == "pv":
self.pv_warning.show()
else:
self.pv_warning.hide()
def update_virt_mode_list(self):
- choices = [('HVM', 'hvm'),
- ('PV', 'pv')]
+ choices = [("HVM", "hvm"), ("PV", "pv")]
if hasattr(self, "dev_list"):
devs_attached = self.dev_list.selected_list.count() != 0
else:
try:
- devs_attached = bool(list(
- self.vm.devices['pci'].get_assigned_devices(
- required_only=True))
+ devs_attached = bool(
+ list(
+ self.vm.devices["pci"].get_assigned_devices(required_only=True)
+ )
)
except qubesadmin.exc.QubesException:
devs_attached = False
@@ -1285,7 +1391,7 @@ def update_virt_mode_list(self):
if devs_attached:
self.pvh_mode_hidden.show()
else:
- choices.insert(0, ('PVH', 'pvh'))
+ choices.insert(0, ("PVH", "pvh"))
self.pvh_mode_hidden.hide()
old_mode = self.virt_mode.currentData()
@@ -1295,20 +1401,25 @@ def update_virt_mode_list(self):
# due to how virtualization mode has uniquely different displayed and
# actual name of the default value, I will add it manually
try:
- choices.insert(0, (
- "default ({})".format(
- self.vm.property_get_default('virt_mode').upper()),
- qubesadmin.DEFAULT))
+ choices.insert(
+ 0,
+ (
+ "default ({})".format(
+ self.vm.property_get_default("virt_mode").upper()
+ ),
+ qubesadmin.DEFAULT,
+ ),
+ )
except qubesadmin.exc.QubesException:
- choices.insert(0,
- ("default ({SYSTEM DEFAULT})", qubesadmin.DEFAULT))
+ choices.insert(0, ("default ({SYSTEM DEFAULT})", qubesadmin.DEFAULT))
try:
utils.initialize_widget_for_property(
widget=self.virt_mode,
choices=choices,
holder=self.vm,
- property_name='virt_mode')
+ property_name="virt_mode",
+ )
except qubesadmin.exc.QubesDaemonAccessError:
self.virt_mode.setEnabled(False)
@@ -1321,7 +1432,7 @@ def update_virt_mode_list(self):
self.update_pvh_kernel_ver_warning()
def update_pvh_kernel_ver_warning(self):
- if self.virt_mode.currentData() != 'pvh':
+ if self.virt_mode.currentData() != "pvh":
self.pvh_kernel_version_warning.hide()
return
@@ -1345,9 +1456,9 @@ def pvh_kernel_version_ok(self, name):
return False
if name is qubesadmin.DEFAULT:
- name = getattr(self.vm.app, 'default_kernel', None)
+ name = getattr(self.vm.app, "default_kernel", None)
- m = re.search(r'(\d+)\.(\d+)', name)
+ m = re.search(r"(\d+)\.(\d+)", name)
if m is None:
return False
@@ -1359,8 +1470,7 @@ def update_bootmode_kernel_opts(self):
if isinstance(active_bootmode, str):
self.bootmode_kernel_opts.setText(
self.vm.features.check_with_template(
- f"boot-mode.kernelopts.{active_bootmode}",
- ""
+ f"boot-mode.kernelopts.{active_bootmode}", ""
)
)
else:
@@ -1370,8 +1480,7 @@ def update_bootmode_kernel_opts(self):
else:
self.bootmode_kernel_opts.setText(
self.vm.features.check_with_template(
- f"boot-mode.kernelopts.{default_bootmode}",
- ""
+ f"boot-mode.kernelopts.{default_bootmode}", ""
)
)
@@ -1383,7 +1492,8 @@ def __init_devices_tab__(self):
self.dev_list = multiselectwidget.MultiSelectWidget(self)
self.dev_list.change_labels(
available="Available devices",
- selected="Devices always connected to this qube")
+ selected="Devices always connected to this qube",
+ )
self.dev_list.add_all_button.setVisible(False)
self.devices_layout.addWidget(self.dev_list)
@@ -1397,10 +1507,11 @@ def __init_devices_tab__(self):
!= device_protocol.DeviceCategory.PCI_Bridge
)
attached = list(
- self.vm.devices['pci'].get_assigned_devices(required_only=True))
+ self.vm.devices["pci"].get_assigned_devices(required_only=True)
+ )
except qubesadmin.exc.QubesException:
# no permission to access devices
- self.tabWidget.setTabEnabled(self.tabs_indices['devices'], False)
+ self.tabWidget.setTabEnabled(self.tabs_indices["devices"], False)
return
# pylint: disable=too-few-public-methods
@@ -1413,7 +1524,7 @@ def __init__(self, dev, unknown=False, parent=None):
+ dev.description
)
if unknown:
- name += ' (unknown)'
+ name += " (unknown)"
self.setText(name)
self.dev = dev
@@ -1425,10 +1536,13 @@ def __init__(self, dev, unknown=False, parent=None):
for ass in attached:
if not any(ass.matches(dev) for dev in dom0_devs):
self.dev_list.selected_list.addItem(
- DevListWidgetItem(ass.device, unknown=True))
+ DevListWidgetItem(ass.device, unknown=True)
+ )
- if self.dev_list.selected_list.count() > 0\
- and self.include_in_balancing.isChecked():
+ if (
+ self.dev_list.selected_list.count() > 0
+ and self.include_in_balancing.isChecked()
+ ):
self.dmm_warning_adv.show()
self.dmm_warning_dev.show()
else:
@@ -1450,45 +1564,48 @@ def __init__(self, dev, unknown=False, parent=None):
def __apply_devices_tab__(self):
msg = []
- if not self.tabWidget.isTabEnabled(self.tabs_indices['devices']):
+ if not self.tabWidget.isTabEnabled(self.tabs_indices["devices"]):
return msg
try:
old_devs = list(
- self.vm.devices['pci'].get_assigned_devices(required_only=True))
+ self.vm.devices["pci"].get_assigned_devices(required_only=True)
+ )
- new_devs = [self.dev_list.selected_list.item(i).dev
- for i in range(self.dev_list.selected_list.count())]
+ new_devs = [
+ self.dev_list.selected_list.item(i).dev
+ for i in range(self.dev_list.selected_list.count())
+ ]
for dev in new_devs:
- old_assignments = [old for old in old_devs
- if old.matches(dev)]
+ old_assignments = [old for old in old_devs if old.matches(dev)]
if not old_assignments:
options = {}
if dev.port_id in self.new_strict_reset_list:
- options['no-strict-reset'] = True
+ options["no-strict-reset"] = True
ass = device_protocol.DeviceAssignment.new(
- backend_domain=self.vm.app.domains['dom0'],
+ backend_domain=self.vm.app.domains["dom0"],
port_id=dev.port_id,
- devclass='pci',
- mode='required',
+ devclass="pci",
+ mode="required",
options=options,
)
- self.vm.devices['pci'].assign(ass)
- elif (dev.port_id in self.current_strict_reset_list) != \
- (dev.port_id in self.new_strict_reset_list):
+ self.vm.devices["pci"].assign(ass)
+ elif (dev.port_id in self.current_strict_reset_list) != (
+ dev.port_id in self.new_strict_reset_list
+ ):
current_assignment = old_assignments[0]
- self.vm.devices['pci'].unassign(current_assignment)
+ self.vm.devices["pci"].unassign(current_assignment)
- current_assignment.options['no-strict-reset'] = \
+ current_assignment.options["no-strict-reset"] = (
dev.port_id in self.new_strict_reset_list
+ )
- self.vm.devices['pci'].assign(current_assignment)
+ self.vm.devices["pci"].assign(current_assignment)
- for ass in self.vm.devices['pci'].get_assigned_devices(
- required_only=True):
+ for ass in self.vm.devices["pci"].get_assigned_devices(required_only=True):
if ass.device not in new_devs:
- self.vm.devices['pci'].unassign(ass)
+ self.vm.devices["pci"].unassign(ass)
except qubesadmin.exc.QubesException as ex:
if utils.is_debug():
@@ -1511,7 +1628,7 @@ def devices_selection_changed(self):
def update_pvh_dont_support_devs(self):
# this is the easiest way to check for both normal 'PVH' and
# default (PVH) options
- if 'PVH' in self.virt_mode.currentText().upper():
+ if "PVH" in self.virt_mode.currentText().upper():
self.dev_list.setEnabled(False)
self.pvh_dont_support_devs.setVisible(True)
else:
@@ -1519,17 +1636,23 @@ def update_pvh_dont_support_devs(self):
self.pvh_dont_support_devs.setVisible(False)
def define_strict_reset_devices(self):
- for assignment in self.vm.devices['pci'].get_assigned_devices(
- required_only=True):
- if assignment.options.get('no-strict-reset', False):
+ for assignment in self.vm.devices["pci"].get_assigned_devices(
+ required_only=True
+ ):
+ if assignment.options.get("no-strict-reset", False):
self.current_strict_reset_list.append(
- assignment.port_id.replace('_', ':'))
+ assignment.port_id.replace("_", ":")
+ )
self.new_strict_reset_list = self.current_strict_reset_list.copy()
def strict_reset_button_pressed(self):
device_list_window = device_list.PCIDeviceListWindow(
- vm=self.vm, qapp=self.qapp, dev_list=self.dev_list,
- no_strict_reset_list=self.new_strict_reset_list, parent=self)
+ vm=self.vm,
+ qapp=self.qapp,
+ dev_list=self.dev_list,
+ no_strict_reset_list=self.new_strict_reset_list,
+ parent=self,
+ )
device_list_window.exec()
######## applications tab
@@ -1537,7 +1660,7 @@ def strict_reset_button_pressed(self):
def refresh_apps_button_pressed(self):
self.refresh_apps_button.setEnabled(False)
- self.refresh_apps_button.setText(self.tr('Refresh in progress...'))
+ self.refresh_apps_button.setText(self.tr("Refresh in progress..."))
thread = RefreshAppsVMThread(self.vm, self.refresh_apps_button)
thread.finished.connect(self.clear_threads)
@@ -1548,15 +1671,17 @@ def refresh_apps_button_pressed(self):
def refresh_finished(self):
self.app_list_manager = AppmenuSelectManager(self.vm, self.app_list)
self.refresh_apps_button.setEnabled(True)
- self.refresh_apps_button.setText(self.tr('Refresh applications'))
+ self.refresh_apps_button.setText(self.tr("Refresh applications"))
def template_apps_change(self):
if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]):
self.app_list_manager.fill_apps_list(
- template=self.template_name.currentData())
+ template=self.template_name.currentData()
+ )
# add a label to show
self.warn_template_missing_apps.setVisible(
- self.app_list_manager.has_missing)
+ self.app_list_manager.has_missing
+ )
######## services tab
@@ -1564,15 +1689,18 @@ def __init_services_tab__(self):
self.new_srv_dict = {}
try:
for feature in self.vm.features:
- if not feature.startswith(SERVICE_PREFIX) or \
- feature in INTERNAL_SERVICE_FEATURES:
+ if (
+ not feature.startswith(SERVICE_PREFIX)
+ or feature in INTERNAL_SERVICE_FEATURES
+ ):
continue
- service = feature[len(SERVICE_PREFIX):]
+ service = feature[len(SERVICE_PREFIX) :]
item = QtWidgets.QListWidgetItem(service)
item.setCheckState(
ui_settingsdlg.QtCore.Qt.CheckState.Checked
if self.vm.features[feature]
- else ui_settingsdlg.QtCore.Qt.CheckState.Unchecked)
+ else ui_settingsdlg.QtCore.Qt.CheckState.Unchecked
+ )
self.services_list.addItem(item)
self.new_srv_dict[service] = self.vm.features[feature]
except qubesadmin.exc.QubesDaemonAccessError:
@@ -1584,32 +1712,33 @@ def __init_services_tab__(self):
supported_services = set()
for feature in self.vm.features:
- if feature.startswith(SUPPORTED_SERVICE_PREFIX) and \
- feature not in INTERNAL_SUPPORTED_FEATURES:
- supported_services.add(feature[len(SUPPORTED_SERVICE_PREFIX):])
+ if (
+ feature.startswith(SUPPORTED_SERVICE_PREFIX)
+ and feature not in INTERNAL_SUPPORTED_FEATURES
+ ):
+ supported_services.add(feature[len(SUPPORTED_SERVICE_PREFIX) :])
if getattr(self.vm, "template", None):
try:
for feature in self.vm.template.features:
- if feature.startswith(SUPPORTED_SERVICE_PREFIX) and \
- feature not in INTERNAL_SUPPORTED_FEATURES:
- supported_services.add(
- feature[len(SUPPORTED_SERVICE_PREFIX):])
+ if (
+ feature.startswith(SUPPORTED_SERVICE_PREFIX)
+ and feature not in INTERNAL_SUPPORTED_FEATURES
+ ):
+ supported_services.add(feature[len(SUPPORTED_SERVICE_PREFIX) :])
except qubesadmin.exc.QubesDaemonAccessError:
pass
for service in sorted(supported_services):
self.service_line_edit.addItem(service)
- self.service_line_edit.addItem(self.tr('(custom...)'))
+ self.service_line_edit.addItem(self.tr("(custom...)"))
self.service_line_edit.setEditText("")
def __init_notes_tab__(self):
try:
self.notes.setPlainText(self.vm.get_notes())
except qubesadmin.exc.QubesException:
- self.notes.setPlainText(
- "Could not retrieve notes for this qube "
- )
+ self.notes.setPlainText("Could not retrieve notes for this qube ")
self.notes.setEnabled(False)
def __apply_notes_tab__(self):
@@ -1624,21 +1753,20 @@ def __add_service__(self):
srv = str(self.service_line_edit.currentText()).strip()
if srv != "":
- if self.service_line_edit.currentIndex() == \
- len(self.service_line_edit) - 1:
+ if self.service_line_edit.currentIndex() == len(self.service_line_edit) - 1:
(custom_name, ok) = QtWidgets.QInputDialog.getText(
- self, self.tr("Custom service name"),
- self.tr(
- "Name of the service:"))
+ self,
+ self.tr("Custom service name"),
+ self.tr("Name of the service:"),
+ )
if ok:
srv = custom_name.strip()
else:
return
if srv in self.new_srv_dict:
QtWidgets.QMessageBox.information(
- self,
- '',
- self.tr('Service already on the list!'))
+ self, "", self.tr("Service already on the list!")
+ )
return
item = QtWidgets.QListWidgetItem(srv)
item.setCheckState(ui_settingsdlg.QtCore.Qt.CheckState.Checked)
@@ -1658,27 +1786,29 @@ def __remove_service__(self):
def __apply_services_tab__(self):
msg = []
- if not self.tabWidget.isTabEnabled(self.tabs_indices['services']):
+ if not self.tabWidget.isTabEnabled(self.tabs_indices["services"]):
return msg
try:
for i in range(self.services_list.count()):
item = self.services_list.item(i)
- self.new_srv_dict[str(item.text())] = \
- (item.checkState() ==
- QtCore.Qt.CheckState.Checked)
+ self.new_srv_dict[str(item.text())] = (
+ item.checkState() == QtCore.Qt.CheckState.Checked
+ )
for service, v in self.new_srv_dict.items():
feature = SERVICE_PREFIX + service
- val = '1' if v else ''
+ val = "1" if v else ""
if val != self.vm.features.get(feature, object()):
self.vm.features[feature] = val
for feature in self.vm.features:
- if not feature.startswith(SERVICE_PREFIX) or \
- feature in INTERNAL_SERVICE_FEATURES:
+ if (
+ not feature.startswith(SERVICE_PREFIX)
+ or feature in INTERNAL_SERVICE_FEATURES
+ ):
continue
- service = feature[len(SERVICE_PREFIX):]
+ service = feature[len(SERVICE_PREFIX) :]
if service not in self.new_srv_dict:
del self.vm.features[feature]
except qubesadmin.exc.QubesException as ex:
@@ -1691,14 +1821,17 @@ def set_fw_model(self, model):
self.fw_model = model
self.rulesTreeView.setModel(model)
self.rulesTreeView.header().setSectionResizeMode(
- QtWidgets.QHeaderView.ResizeMode.ResizeToContents)
+ QtWidgets.QHeaderView.ResizeMode.ResizeToContents
+ )
self.rulesTreeView.header().setSectionResizeMode(
- 0, QtWidgets.QHeaderView.ResizeMode.Stretch)
+ 0, QtWidgets.QHeaderView.ResizeMode.Stretch
+ )
self.set_allow(model.allow)
if model.temp_full_access_expire_time:
self.temp_full_access.setChecked(True)
- expire_time = model.temp_full_access_expire_time - \
- datetime.datetime.now().timestamp()
+ expire_time = (
+ model.temp_full_access_expire_time - datetime.datetime.now().timestamp()
+ )
self.temp_full_access_time.setValue(int(expire_time / 60))
def disable_all_fw_conf(self):
@@ -1718,18 +1851,12 @@ def set_allow(self, allow):
self.policy_changed()
def policy_changed(self):
- self.rulesTreeView.setEnabled(
- self.policy_deny_radio_button.isChecked())
- self.new_rule_button.setEnabled(
- self.policy_deny_radio_button.isChecked())
- self.edit_rule_button.setEnabled(
- self.policy_deny_radio_button.isChecked())
- self.delete_rule_button.setEnabled(
- self.policy_deny_radio_button.isChecked())
- self.firewal_rules_label.setEnabled(
- self.policy_deny_radio_button.isChecked())
- self.tempFullAccessWidget.setEnabled(
- self.policy_deny_radio_button.isChecked())
+ self.rulesTreeView.setEnabled(self.policy_deny_radio_button.isChecked())
+ self.new_rule_button.setEnabled(self.policy_deny_radio_button.isChecked())
+ self.edit_rule_button.setEnabled(self.policy_deny_radio_button.isChecked())
+ self.delete_rule_button.setEnabled(self.policy_deny_radio_button.isChecked())
+ self.firewal_rules_label.setEnabled(self.policy_deny_radio_button.isChecked())
+ self.tempFullAccessWidget.setEnabled(self.policy_deny_radio_button.isChecked())
def new_rule_button_pressed(self):
dialog = firewall.NewFwRuleDlg(parent=self)
@@ -1747,34 +1874,39 @@ def edit_rule_button_pressed(self):
self.fw_model.run_rule_dialog(dialog, row)
def delete_rule_button_pressed(self):
- for i in {index.row() for index
- in self.rulesTreeView.selectedIndexes()}:
+ for i in {index.row() for index in self.rulesTreeView.selectedIndexes()}:
self.fw_model.remove_child(i)
parser = QubesArgumentParser(vmname_nargs=1)
-parser.add_argument('--tab', metavar='TAB',
- action='store',
- choices=VMSettingsWindow.tabs_indices.keys())
+parser.add_argument(
+ "--tab",
+ metavar="TAB",
+ action="store",
+ choices=VMSettingsWindow.tabs_indices.keys(),
+)
parser.set_defaults(
- tab='basic',
+ tab="basic",
)
def main(args=None):
args = parser.parse_args(args)
vm = args.domains.pop()
- if vm.klass == 'AdminVM':
- print("This tool cannot be used to change properties of an "
- f"AdminVM ({vm.name}).")
- print("You can use command-line tools such as qvm-prefs "
- "and qvm-features to change properties of an AdminVM")
+ if vm.klass == "AdminVM":
+ print(
+ "This tool cannot be used to change properties of an "
+ f"AdminVM ({vm.name})."
+ )
+ print(
+ "You can use command-line tools such as qvm-prefs "
+ "and qvm-features to change properties of an AdminVM"
+ )
return 1
- utils.run_synchronous(functools.partial(VMSettingsWindow, vm.name,
- args.tab))
+ utils.run_synchronous(functools.partial(VMSettingsWindow, vm.name, args.tab))
if __name__ == "__main__":
diff --git a/qubesmanager/tests/test_vm_settings.py b/qubesmanager/tests/test_vm_settings.py
index 846fc1f3..37d6bf4a 100644
--- a/qubesmanager/tests/test_vm_settings.py
+++ b/qubesmanager/tests/test_vm_settings.py
@@ -31,8 +31,14 @@
PAGES = ["basic", "advanced", "firewall", "devices", "applications", "services"]
# just vms
-TEST_VMS = ["test-red", "test-blue", "sys-net",
- "test-standalone", "test-old", "test-vm-set"]
+TEST_VMS = [
+ "test-red",
+ "test-blue",
+ "sys-net",
+ "test-standalone",
+ "test-old",
+ "test-vm-set",
+]
# with a template
ALL_TEST_VMS = TEST_VMS + ["fedora-35"]
@@ -46,140 +52,192 @@
def mock_subprocess_complex(command):
vm_name = command[-1]
- if command[1] == '--get-available':
- if vm_name == 'test-vm-set':
- return (b'test.desktop|Test App||\n'
- b'test2.desktop|Test2 App| test2|\n'
- b'test3.desktop|Test3 App||\n'
- b'myvm.desktop|My VM app||\n')
- elif vm_name == 'fedora-36':
- return b'tpl.desktop|Template App||\n'
+ if command[1] == "--get-available":
+ if vm_name == "test-vm-set":
+ return (
+ b"test.desktop|Test App||\n"
+ b"test2.desktop|Test2 App| test2|\n"
+ b"test3.desktop|Test3 App||\n"
+ b"myvm.desktop|My VM app||\n"
+ )
+ elif vm_name == "fedora-36":
+ return b"tpl.desktop|Template App||\n"
else:
- return (b'test.desktop|Test App||\n'
- b'test2.desktop|Test2 App| test2|\n'
- b'test3.desktop|Test3 App||\n')
- elif command[1] == '--get-whitelist':
- if vm_name == 'test-vm-set':
- return b'test.desktop\nmissing.desktop'
+ return (
+ b"test.desktop|Test App||\n"
+ b"test2.desktop|Test2 App| test2|\n"
+ b"test3.desktop|Test3 App||\n"
+ )
+ elif command[1] == "--get-whitelist":
+ if vm_name == "test-vm-set":
+ return b"test.desktop\nmissing.desktop"
else:
- return b''
- return b''
+ return b""
+ return b""
@pytest.fixture
-def settings_fixture(request, qapp, test_qubes_app) -> Tuple[
- vm_settings.VMSettingsWindow, str, str]:
+def settings_fixture(
+ request, qapp, test_qubes_app
+) -> Tuple[vm_settings.VMSettingsWindow, str, str]:
# add a frankenqube with worst possible settings
fw_rules = [
{"action": "accept", "dsthost": "qubes-os.org"},
- {"action": "accept", "specialtarget":"dns"},
+ {"action": "accept", "specialtarget": "dns"},
{"action": "accept", "proto": "icmp"},
- {"action": "drop"}
+ {"action": "drop"},
]
- test_qubes_app._qubes['test-vm-set'] = MockQube(
- name="test-vm-set", qapp=test_qubes_app, label="green",
- template='fedora-36', include_in_backups=False, autostart=True,
- kernel='1.1', virt_mode='hvm', provides_network=True,
- usage=0.5, template_for_dispvms=True, features={
- 'gui-allow-fullscreen': '1', 'gui-allow-utf8-titles': '1',
- 'supported-service.qubes-u2f-proxy': '1',
- 'service.qubes-u2f-proxy': '1', 'supported-service.clocksync': '1'},
- firewall_rules=fw_rules
+ test_qubes_app._qubes["test-vm-set"] = MockQube(
+ name="test-vm-set",
+ qapp=test_qubes_app,
+ label="green",
+ template="fedora-36",
+ include_in_backups=False,
+ autostart=True,
+ kernel="1.1",
+ virt_mode="hvm",
+ provides_network=True,
+ usage=0.5,
+ template_for_dispvms=True,
+ features={
+ "gui-allow-fullscreen": "1",
+ "gui-allow-utf8-titles": "1",
+ "supported-service.qubes-u2f-proxy": "1",
+ "service.qubes-u2f-proxy": "1",
+ "supported-service.clocksync": "1",
+ },
+ firewall_rules=fw_rules,
)
# and add a qube that has a connected pci device
- test_qubes_app._qubes['test-pci-dev'] = MockQube(
- name="test-pci-dev", qapp=test_qubes_app, label="green",
- virt_mode='hvm'
+ test_qubes_app._qubes["test-pci-dev"] = MockQube(
+ name="test-pci-dev", qapp=test_qubes_app, label="green", virt_mode="hvm"
)
- test_qubes_app._qubes['sys-whonix'] = MockQube(
- name="sys-whonix", qapp=test_qubes_app, tags=['anon-gateway'])
+ test_qubes_app._qubes["sys-whonix"] = MockQube(
+ name="sys-whonix", qapp=test_qubes_app, tags=["anon-gateway"]
+ )
- test_qubes_app._qubes['anon-whonix'] = MockQube(
- name="anon-whonix", qapp=test_qubes_app, tags=['anon-vm'])
+ test_qubes_app._qubes["anon-whonix"] = MockQube(
+ name="anon-whonix", qapp=test_qubes_app, tags=["anon-vm"]
+ )
test_qubes_app._devices.append(
MockDevice(
- test_qubes_app, dev_class='pci',
- device_id='0x8008:0x1234::p040000', backend_vm='dom0',
- port='00_04.3', product='Important Device', vendor='Test',
- assigned=[('test-pci-dev', 'required', None)]))
+ test_qubes_app,
+ dev_class="pci",
+ device_id="0x8008:0x1234::p040000",
+ backend_vm="dom0",
+ port="00_04.3",
+ product="Important Device",
+ vendor="Test",
+ assigned=[("test-pci-dev", "required", None)],
+ )
+ )
# add a TemplateVM with some boot modes
- test_qubes_app._qubes['fedora-36-bootmodes'] = MockQube(
- name="fedora-36-bootmodes", qapp=test_qubes_app, klass="TemplateVM",
- netvm="", features={'boot-mode.kernelopts.mode1': 'mode1kern',
- 'boot-mode.name.mode1': 'Mode One',
- 'boot-mode.kernelopts.mode2': 'mode2kern1 mode2kern2',
- 'boot-mode.active': 'mode1', 'boot-mode.appvm-default': 'mode2'}
+ test_qubes_app._qubes["fedora-36-bootmodes"] = MockQube(
+ name="fedora-36-bootmodes",
+ qapp=test_qubes_app,
+ klass="TemplateVM",
+ netvm="",
+ features={
+ "boot-mode.kernelopts.mode1": "mode1kern",
+ "boot-mode.name.mode1": "Mode One",
+ "boot-mode.kernelopts.mode2": "mode2kern1 mode2kern2",
+ "boot-mode.active": "mode1",
+ "boot-mode.appvm-default": "mode2",
+ },
)
# add an AppVM on top of the bootmode-enabled template
- test_qubes_app._qubes['test-vm-bootmodes'] = MockQube(
- name="test-vm-bootmodes", qapp=test_qubes_app,
- template="fedora-36-bootmodes", features={
- 'boot-mode.kernelopts.mode1': 'mode1kern',
- 'boot-mode.name.mode1': 'Mode One',
- 'boot-mode.kernelopts.mode2': 'mode2kern1 mode2kern2',
- 'boot-mode.active': 'mode1', 'boot-mode.appvm-default': 'mode2'}
+ test_qubes_app._qubes["test-vm-bootmodes"] = MockQube(
+ name="test-vm-bootmodes",
+ qapp=test_qubes_app,
+ template="fedora-36-bootmodes",
+ features={
+ "boot-mode.kernelopts.mode1": "mode1kern",
+ "boot-mode.name.mode1": "Mode One",
+ "boot-mode.kernelopts.mode2": "mode2kern1 mode2kern2",
+ "boot-mode.active": "mode1",
+ "boot-mode.appvm-default": "mode2",
+ },
)
# add another AppVM with a non-default bootmode set
- test_qubes_app._qubes['test-vm-bootmodes-nondefault'] = MockQube(
- name="test-vm-bootmodes-nondefault", qapp=test_qubes_app,
- template="fedora-36-bootmodes", bootmode="mode2", features={
- 'boot-mode.kernelopts.mode1': 'mode1kern',
- 'boot-mode.name.mode1': 'Mode One',
- 'boot-mode.kernelopts.mode2': 'mode2kern1 mode2kern2',
- 'boot-mode.active': 'mode1', 'boot-mode.appvm-default': 'mode2'}
+ test_qubes_app._qubes["test-vm-bootmodes-nondefault"] = MockQube(
+ name="test-vm-bootmodes-nondefault",
+ qapp=test_qubes_app,
+ template="fedora-36-bootmodes",
+ bootmode="mode2",
+ features={
+ "boot-mode.kernelopts.mode1": "mode1kern",
+ "boot-mode.name.mode1": "Mode One",
+ "boot-mode.kernelopts.mode2": "mode2kern1 mode2kern2",
+ "boot-mode.active": "mode1",
+ "boot-mode.appvm-default": "mode2",
+ },
)
test_qubes_app.update_vm_calls()
if isinstance(request.param, dict):
- vm = test_qubes_app.domains[request.param['vm']]
- page = request.param['page']
+ vm = test_qubes_app.domains[request.param["vm"]]
+ page = request.param["page"]
else:
vm = test_qubes_app.domains[request.param]
- page = 'basic'
- with mock.patch('subprocess.check_output') as mock_subprocess:
+ page = "basic"
+ with mock.patch("subprocess.check_output") as mock_subprocess:
mock_subprocess.side_effect = mock_subprocess_complex
- expected_call = (vm.name, 'admin.vm.notes.Get', None, None)
- test_qubes_app.expected_calls[expected_call] = b'0\x00Some Notes\x00'
- vms = vm_settings.VMSettingsWindow(vm, page, qapp,
- test_qubes_app)
-
+ expected_call = (vm.name, "admin.vm.notes.Get", None, None)
+ test_qubes_app.expected_calls[expected_call] = b"0\x00Some Notes\x00"
+ expected_call_preload = (
+ vm.name,
+ "admin.vm.feature.Get",
+ "preload-dispvm-max",
+ None,
+ )
+ test_qubes_app.expected_calls[expected_call_preload] = b"0\x00"
+ expected_call_preload = (
+ "dom0",
+ "admin.vm.feature.Get",
+ "preload-dispvm-max",
+ None,
+ )
+ test_qubes_app.expected_calls[expected_call_preload] = b"0\x00"
+ vms = vm_settings.VMSettingsWindow(vm, page, qapp, test_qubes_app)
yield vms, page, vm.name
+
+
# TODO: found a bug: firewall warning does not update
def check_errors(test_function):
@wraps(test_function)
def wrapper(*args, **kwargs):
- with mock.patch('PyQt6.QtWidgets.QMessageBox.warning') as mock_warning:
+ with mock.patch("PyQt6.QtWidgets.QMessageBox.warning") as mock_warning:
result = test_function(*args, **kwargs)
if mock_warning.call_count > 0:
err = mock_warning.mock_calls[0][1][2]
assert False, err
assert mock_warning.call_count == 0
return result
+
return wrapper
-def _select_item(combobox: QtWidgets.QComboBox, text: str,
- match_strict: bool = False):
+def _select_item(combobox: QtWidgets.QComboBox, text: str, match_strict: bool = False):
"""
select a given item in the combobox; if match_strict is True, will only
match exact matches, otherwise, will match any item that contains
provided string.
"""
for i in range(combobox.count()):
- item_text = str(combobox.itemData(i,
- QtCore.Qt.ItemDataRole.DisplayRole))
- if (match_strict and item_text == text) or (not match_strict and text
- in item_text):
+ item_text = str(combobox.itemData(i, QtCore.Qt.ItemDataRole.DisplayRole))
+ if (match_strict and item_text == text) or (
+ not match_strict and text in item_text
+ ):
combobox.setCurrentIndex(i)
return
assert False, "Failed to find " + text
@@ -212,7 +270,7 @@ def test_002_data(settings_fixture):
# check if contents are reasonable
# basic tab
- if hasattr(vm, 'template'):
+ if hasattr(vm, "template"):
assert str(vm.template) in settings_window.template_name.currentText()
else:
assert settings_window.template_name.currentText() == ""
@@ -229,50 +287,57 @@ def test_002_data(settings_fixture):
assert str(vm.label) in settings_window.vmlabel.currentText()
- assert (settings_window.include_in_backups.isChecked() ==
- getattr(vm, "include_in_backups", False))
+ assert settings_window.include_in_backups.isChecked() == getattr(
+ vm, "include_in_backups", False
+ )
- assert (settings_window.autostart_vm.isChecked() ==
- getattr(vm, "autostart", False))
+ assert settings_window.autostart_vm.isChecked() == getattr(vm, "autostart", False)
# advanced tab
assert settings_window.run_in_debug_mode.isChecked() == vm.debug
- assert (settings_window.provides_network_checkbox.isChecked() ==
- getattr(vm, "provides_network", False))
- assert settings_window.dvm_template_checkbox.isChecked() == \
- getattr(vm, 'template_for_dispvms', False)
-
- if hasattr(vm, 'default_dispvm'):
- if vm.property_is_default('default_dispvm'):
- assert 'default' in settings_window.default_dispvm.currentText()
+ assert settings_window.provides_network_checkbox.isChecked() == getattr(
+ vm, "provides_network", False
+ )
+ assert settings_window.dvm_template_checkbox.isChecked() == getattr(
+ vm, "template_for_dispvms", False
+ )
+ assert (
+ settings_window.preload_dispvm.isEnabled()
+ == settings_window.dvm_template_checkbox.isChecked()
+ )
+
+ if hasattr(vm, "default_dispvm"):
+ if vm.property_is_default("default_dispvm"):
+ assert "default" in settings_window.default_dispvm.currentText()
if vm.default_dispvm:
- assert (str(vm.default_dispvm) in
- settings_window.default_dispvm.currentText())
+ assert (
+ str(vm.default_dispvm) in settings_window.default_dispvm.currentText()
+ )
else:
- assert ("none" in
- settings_window.default_dispvm.currentText().lower())
+ assert "none" in settings_window.default_dispvm.currentText().lower()
else:
assert not settings_window.default_dispvm.isEnabled()
- if hasattr(vm, 'kernel'):
+ if hasattr(vm, "kernel"):
assert vm.kernel in settings_window.kernel.currentText()
- if hasattr(vm, 'virt_mode'):
+ if hasattr(vm, "virt_mode"):
assert vm.virt_mode.upper() in settings_window.virt_mode.currentText()
# BASIC TAB
# changing label
+
@check_errors
@pytest.mark.parametrize("settings_fixture", ALL_TEST_VMS, indirect=True)
def test_100_change_label(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- change_needed = str(vm.label) != 'red'
+ change_needed = str(vm.label) != "red"
if vm.is_running():
assert not settings_window.vmlabel.isEnabled()
@@ -284,19 +349,21 @@ def test_100_change_label(settings_fixture):
# is red, while others are green
_select_item(settings_window.vmlabel, "red")
- expected_call = (vm_name, 'admin.vm.property.Set', 'label', b'red')
+ expected_call = (vm_name, "admin.vm.property.Set", "label", b"red")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
if change_needed:
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Label not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Label not changed"
else:
- assert expected_call not in settings_window.qubesapp.actual_calls, \
- "Unnecessary label change"
+ assert (
+ expected_call not in settings_window.qubesapp.actual_calls
+ ), "Unnecessary label change"
@check_errors
@@ -309,26 +376,28 @@ def test_101_change_template(settings_fixture):
assert not settings_window.template_name.isEnabled()
return
- change_needed = str(vm.template) != 'fedora-35'
+ change_needed = str(vm.template) != "fedora-35"
assert settings_window.template_name.isEnabled()
# one of the vms (test-old) already has this template
_select_item(settings_window.template_name, "fedora-35")
- expected_call = (vm_name, 'admin.vm.property.Set', 'template', b'fedora-35')
+ expected_call = (vm_name, "admin.vm.property.Set", "template", b"fedora-35")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
if change_needed:
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Template not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Template not changed"
else:
- assert expected_call not in settings_window.qubesapp.actual_calls, \
- "Unnecessary template change"
+ assert (
+ expected_call not in settings_window.qubesapp.actual_calls
+ ), "Unnecessary template change"
@check_errors
@@ -337,27 +406,30 @@ def test_102_change_netvm(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- change_needed = str(vm.netvm) != 'sys-net'
+ change_needed = str(vm.netvm) != "sys-net"
assert settings_window.netVM.isEnabled()
_select_item(settings_window.netVM, "sys-net")
- expected_call = (vm_name, 'admin.vm.property.Set', 'netvm', b'sys-net')
+ expected_call = (vm_name, "admin.vm.property.Set", "netvm", b"sys-net")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
if change_needed:
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "NetVM not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "NetVM not changed"
else:
- assert expected_call not in settings_window.qubesapp.actual_calls, \
- "Unnecessary NetVM change"
+ assert (
+ expected_call not in settings_window.qubesapp.actual_calls
+ ), "Unnecessary NetVM change"
-@mock.patch('PyQt6.QtWidgets.QMessageBox.warning')
+
+@mock.patch("PyQt6.QtWidgets.QMessageBox.warning")
@pytest.mark.parametrize("settings_fixture", ["fedora-35"], indirect=True)
def test_103_change_netvm_tpl(mock_warning, settings_fixture):
settings_window, page, vm_name = settings_fixture
@@ -367,18 +439,18 @@ def test_103_change_netvm_tpl(mock_warning, settings_fixture):
_select_item(settings_window.netVM, "sys-net")
- expected_call = (vm_name, 'admin.vm.property.Set', 'netvm', b'sys-net')
+ expected_call = (vm_name, "admin.vm.property.Set", "netvm", b"sys-net")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
- assert mock_warning.call_count == 1, ("Didn't warn for changing netvm "
- "on a template")
+ assert mock_warning.call_count == 1, (
+ "Didn't warn for changing netvm " "on a template"
+ )
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "NetVM not changed"
+ assert expected_call in settings_window.qubesapp.actual_calls, "NetVM not changed"
@check_errors
@@ -393,25 +465,27 @@ def test_104_change_netvm_default(settings_fixture):
_select_item(settings_window.netVM, "default")
- expected_call = (vm_name, 'admin.vm.property.Reset', 'netvm', None)
+ expected_call = (vm_name, "admin.vm.property.Reset", "netvm", None)
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
# when asking to change netvm of a running vm to halted vm, complaints will
# ensue
- with mock.patch('PyQt6.QtWidgets.QMessageBox.question') as mock_question:
+ with mock.patch("PyQt6.QtWidgets.QMessageBox.question") as mock_question:
mock_question.return_value = QtWidgets.QMessageBox.StandardButton.No
settings_window.accept()
if change_needed:
return
if change_needed:
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "NetVM not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "NetVM not changed"
else:
- assert expected_call not in settings_window.qubesapp.actual_calls, \
- "Unnecessary NetVM change"
+ assert (
+ expected_call not in settings_window.qubesapp.actual_calls
+ ), "Unnecessary NetVM change"
@check_errors
@@ -421,21 +495,26 @@ def test_105_incl_in_backups(settings_fixture):
vm = settings_window.qubesapp.domains[vm_name]
assert settings_window.include_in_backups.isEnabled()
- assert (settings_window.include_in_backups.isChecked() ==
- vm.include_in_backups)
+ assert settings_window.include_in_backups.isChecked() == vm.include_in_backups
- expected_call = (vm_name, 'admin.vm.property.Set', 'include_in_backups',
- str(not vm.include_in_backups).encode())
+ expected_call = (
+ vm_name,
+ "admin.vm.property.Set",
+ "include_in_backups",
+ str(not vm.include_in_backups).encode(),
+ )
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.include_in_backups.setChecked(
- not settings_window.include_in_backups.isChecked())
+ not settings_window.include_in_backups.isChecked()
+ )
settings_window.accept()
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Include in backups not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Include in backups not changed"
@check_errors
@@ -445,21 +524,26 @@ def test_106_autostart(settings_fixture):
vm = settings_window.qubesapp.domains[vm_name]
assert settings_window.autostart_vm.isEnabled()
- assert (settings_window.autostart_vm.isChecked() ==
- vm.autostart)
+ assert settings_window.autostart_vm.isChecked() == vm.autostart
- expected_call = (vm_name, 'admin.vm.property.Set', 'autostart',
- str(not vm.autostart).encode())
+ expected_call = (
+ vm_name,
+ "admin.vm.property.Set",
+ "autostart",
+ str(not vm.autostart).encode(),
+ )
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.autostart_vm.setChecked(
- not settings_window.autostart_vm.isChecked())
+ not settings_window.autostart_vm.isChecked()
+ )
settings_window.accept()
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Autostart not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Autostart not changed"
@check_errors
@@ -472,13 +556,12 @@ def test_107_misc_info(settings_fixture):
assert settings_window.ip_label.text() == vm.ip
assert settings_window.netmask_label.text() == vm.visible_netmask
assert settings_window.gateway_label.text() == vm.visible_gateway
- assert settings_window.dns_label.text() == vm.dns.replace(' ', ', ')
+ assert settings_window.dns_label.text() == vm.dns.replace(" ", ", ")
else:
assert not settings_window.networking_groupbox.isEnabled()
assert settings_window.type_label.text() == vm.klass
- assert settings_window.rpm_label.text() == "Yes" if vm.installed_by_rpm \
- else "No"
+ assert settings_window.rpm_label.text() == "Yes" if vm.installed_by_rpm else "No"
@check_errors
@@ -487,7 +570,7 @@ def test_108_disk_space(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- if vm.klass in ['TemplateVM', 'StandaloneVM']:
+ if vm.klass in ["TemplateVM", "StandaloneVM"]:
assert settings_window.root_resize.isEnabled()
else:
assert not settings_window.root_resize.isEnabled()
@@ -495,19 +578,23 @@ def test_108_disk_space(settings_fixture):
assert settings_window.max_priv_storage.isEnabled()
# try to increase one of them
- if vm.klass in ['TemplateVM', 'StandaloneVM']:
+ if vm.klass in ["TemplateVM", "StandaloneVM"]:
expected_value = settings_window.root_resize.value() + 10
- expected_volume = 'root'
+ expected_volume = "root"
settings_window.root_resize.setValue(expected_value)
else:
expected_value = settings_window.max_priv_storage.value() + 10
- expected_volume = 'private'
+ expected_volume = "private"
settings_window.max_priv_storage.setValue(expected_value)
- expected_call = (vm.name, 'admin.vm.volume.Resize', expected_volume,
- str(expected_value * 1024**2).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.volume.Resize",
+ expected_volume,
+ str(expected_value * 1024**2).encode(),
+ )
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
assert expected_call not in settings_window.qubesapp.actual_calls
@@ -518,12 +605,12 @@ def test_108_disk_space(settings_fixture):
# the following tests don't use check_errors fixture, because we want to
# check for errors
-@mock.patch('PyQt6.QtWidgets.QInputDialog.getText')
-@mock.patch('qubesmanager.settings.RenameVMThread')
-@mock.patch('PyQt6.QtWidgets.QMessageBox.warning')
-@pytest.mark.parametrize("settings_fixture", ['fedora-36', 'test-vm-set',
- 'test-blue'],
- indirect=True)
+@mock.patch("PyQt6.QtWidgets.QInputDialog.getText")
+@mock.patch("qubesmanager.settings.RenameVMThread")
+@mock.patch("PyQt6.QtWidgets.QMessageBox.warning")
+@pytest.mark.parametrize(
+ "settings_fixture", ["fedora-36", "test-vm-set", "test-blue"], indirect=True
+)
def test_109_renamevm(mock_warning, mock_thread, mock_input, settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
@@ -538,11 +625,11 @@ def test_109_renamevm(mock_warning, mock_thread, mock_input, settings_fixture):
mock_input.return_value = ("renamed-vm", True)
settings_window.rename_vm_button.click()
- if vm.name == 'fedora-36':
+ if vm.name == "fedora-36":
assert mock_warning.call_count == 1
assert mock_thread.call_count == 0
return
- elif vm.name == 'test-vm-set':
+ elif vm.name == "test-vm-set":
mock_thread.assert_called_with(vm, "renamed-vm", mock.ANY)
mock_thread().start.assert_called_with()
assert mock_warning.call_count == 0
@@ -550,12 +637,12 @@ def test_109_renamevm(mock_warning, mock_thread, mock_input, settings_fixture):
assert mock_warning.call_count == 0
-@mock.patch('PyQt6.QtWidgets.QInputDialog.getText')
-@mock.patch('qubesmanager.common_threads.RemoveVMThread')
-@mock.patch('PyQt6.QtWidgets.QMessageBox.warning')
-@pytest.mark.parametrize("settings_fixture", ['fedora-36', 'test-vm-set',
- 'test-blue'],
- indirect=True)
+@mock.patch("PyQt6.QtWidgets.QInputDialog.getText")
+@mock.patch("qubesmanager.common_threads.RemoveVMThread")
+@mock.patch("PyQt6.QtWidgets.QMessageBox.warning")
+@pytest.mark.parametrize(
+ "settings_fixture", ["fedora-36", "test-vm-set", "test-blue"], indirect=True
+)
def test_110_deletevm(mock_warning, mock_thread, mock_input, settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
@@ -570,11 +657,11 @@ def test_110_deletevm(mock_warning, mock_thread, mock_input, settings_fixture):
mock_input.return_value = (vm.name, True)
settings_window.delete_vm_button.click()
- if vm.name == 'fedora-36':
+ if vm.name == "fedora-36":
assert mock_warning.call_count == 1
assert mock_thread.call_count == 0
return
- elif vm.name == 'test-vm-set':
+ elif vm.name == "test-vm-set":
mock_thread.assert_called_with(vm)
mock_thread().start.assert_called_with()
assert mock_warning.call_count == 0
@@ -582,19 +669,19 @@ def test_110_deletevm(mock_warning, mock_thread, mock_input, settings_fixture):
assert mock_warning.call_count == 0
-@mock.patch('PyQt6.QtWidgets.QInputDialog.getText')
-@mock.patch('qubesmanager.common_threads.RemoveVMThread')
-@mock.patch('PyQt6.QtWidgets.QMessageBox.warning')
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
-def test_111_deletevm_wrong_name(mock_warning, mock_thread, mock_input,
- settings_fixture):
+@mock.patch("PyQt6.QtWidgets.QInputDialog.getText")
+@mock.patch("qubesmanager.common_threads.RemoveVMThread")
+@mock.patch("PyQt6.QtWidgets.QMessageBox.warning")
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
+def test_111_deletevm_wrong_name(
+ mock_warning, mock_thread, mock_input, settings_fixture
+):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
assert settings_window.delete_vm_button.isEnabled()
- mock_input.return_value = (vm.name + 'pomidorek', True)
+ mock_input.return_value = (vm.name + "pomidorek", True)
settings_window.delete_vm_button.click()
assert mock_thread.call_count == 0
@@ -607,11 +694,11 @@ def test_111_deletevm_wrong_name(mock_warning, mock_thread, mock_input,
assert mock_warning.call_count == 1 # no warning, the user cancelled out
-@mock.patch('qubesmanager.clone_vm.CloneVMDlg')
+@mock.patch("qubesmanager.clone_vm.CloneVMDlg")
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['fedora-36', 'test-vm-set',
- 'test-blue'],
- indirect=True)
+@pytest.mark.parametrize(
+ "settings_fixture", ["fedora-36", "test-vm-set", "test-blue"], indirect=True
+)
def test_112_clonevm(mock_clone, settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
@@ -623,14 +710,14 @@ def test_112_clonevm(mock_clone, settings_fixture):
mock_clone.assert_called_with(mock.ANY, mock.ANY, src_vm=vm)
-@mock.patch('PyQt6.QtWidgets.QMessageBox.warning')
+@mock.patch("PyQt6.QtWidgets.QMessageBox.warning")
@pytest.mark.parametrize("settings_fixture", ["anon-whonix"], indirect=True)
def test_113_change_netvm_anon(mock_warning, settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- change_netvm_call = (vm_name, 'admin.vm.property.Set', 'netvm', b'sys-net')
- get_tag_call = (vm_name, 'admin.vm.tag.Get', 'anon-vm', None)
+ change_netvm_call = (vm_name, "admin.vm.property.Set", "netvm", b"sys-net")
+ get_tag_call = (vm_name, "admin.vm.tag.Get", "anon-vm", None)
assert settings_window.netVM.isEnabled()
@@ -639,20 +726,20 @@ def test_113_change_netvm_anon(mock_warning, settings_fixture):
assert get_tag_call in settings_window.qubesapp.actual_calls
assert change_netvm_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[change_netvm_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[change_netvm_call] = b"0\x00"
settings_window.accept()
- settings_window.qubesapp.expected_calls[change_netvm_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[change_netvm_call] = b"0\x00"
- assert mock_warning.call_count == 1, ("Didn't warn for changing netvm "
- "on anon-vm")
+ assert mock_warning.call_count == 1, "Didn't warn for changing netvm " "on anon-vm"
assert change_netvm_call in settings_window.qubesapp.actual_calls
# ADVANCED TAB
+
@check_errors
@pytest.mark.parametrize("settings_fixture", TEST_VMS, indirect=True)
def test_200_init_memory(settings_fixture):
@@ -666,10 +753,14 @@ def test_200_init_memory(settings_fixture):
settings_window.init_mem.setValue(expected_value)
- expected_call = (vm.name, 'admin.vm.property.Set', 'memory',
- str(expected_value).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.property.Set",
+ "memory",
+ str(expected_value).encode(),
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -694,16 +785,28 @@ def test_201_max_memory(settings_fixture):
assert not settings_window.warn_too_much_mem_label.isVisible()
expected_calls = [
- (vm.name, 'admin.vm.property.Set', 'memory',
- str(expected_init).encode()),
- (vm.name, 'admin.vm.property.Set', 'maxmem',
- str(expected_max).encode()),
- (vm.name, 'admin.vm.feature.Set', 'qubesmanager.maxmem_value',
- str(expected_max - 100).encode())
+ (
+ vm.name,
+ "admin.vm.property.Set",
+ "memory",
+ str(expected_init).encode(),
+ ),
+ (
+ vm.name,
+ "admin.vm.property.Set",
+ "maxmem",
+ str(expected_max).encode(),
+ ),
+ (
+ vm.name,
+ "admin.vm.feature.Set",
+ "qubesmanager.maxmem_value",
+ str(expected_max - 100).encode(),
+ ),
]
for call in expected_calls:
assert call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[call] = b"0\x00"
settings_window.accept()
@@ -722,10 +825,14 @@ def test_202_vcpus(settings_fixture):
expected_value = settings_window.vcpus.value() + 1
settings_window.vcpus.setValue(expected_value)
- expected_call = (vm.name, 'admin.vm.property.Set', 'vcpus',
- str(expected_value).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.property.Set",
+ "vcpus",
+ str(expected_value).encode(),
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -742,19 +849,27 @@ def test_203_mem_balancing(settings_fixture):
settings_window.include_in_balancing.setChecked(False)
- expected_call = (vm.name, 'admin.vm.feature.Set',
- 'qubesmanager.maxmem_value', str(vm.maxmem).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Set",
+ "qubesmanager.maxmem_value",
+ str(vm.maxmem).encode(),
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
expected_calls = [
- (vm.name, 'admin.vm.feature.Set', 'qubesmanager.maxmem_value',
- str(vm.maxmem).encode()),
- (vm.name, 'admin.vm.property.Set', 'maxmem', b'0')
+ (
+ vm.name,
+ "admin.vm.feature.Set",
+ "qubesmanager.maxmem_value",
+ str(vm.maxmem).encode(),
+ ),
+ (vm.name, "admin.vm.property.Set", "maxmem", b"0"),
]
for call in expected_calls:
assert call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[call] = b"0\x00"
settings_window.accept()
@@ -772,10 +887,14 @@ def test_204_debug_mode(settings_fixture):
settings_window.run_in_debug_mode.setChecked(not vm.debug)
- expected_call = (vm.name, 'admin.vm.property.Set', 'debug',
- str(not vm.debug).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.property.Set",
+ "debug",
+ str(not vm.debug).encode(),
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -788,16 +907,18 @@ def test_205_povides_network(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- assert (settings_window.provides_network_checkbox.isChecked() ==
- vm.provides_network)
+ assert settings_window.provides_network_checkbox.isChecked() == vm.provides_network
- settings_window.provides_network_checkbox.setChecked(
- not vm.provides_network)
+ settings_window.provides_network_checkbox.setChecked(not vm.provides_network)
- expected_call = (vm.name, 'admin.vm.property.Set', 'provides_network',
- str(not vm.provides_network).encode())
+ expected_call = (
+ vm.name,
+ "admin.vm.property.Set",
+ "provides_network",
+ str(not vm.provides_network).encode(),
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -812,27 +933,40 @@ def test_206_dispvmtempl(settings_fixture):
assert settings_window.dvm_template_checkbox.isEnabled()
- assert (settings_window.dvm_template_checkbox.isChecked() ==
- vm.template_for_dispvms)
+ assert settings_window.dvm_template_checkbox.isChecked() == vm.template_for_dispvms
+ assert (
+ settings_window.preload_dispvm.isEnabled()
+ == settings_window.dvm_template_checkbox.isChecked()
+ )
- settings_window.dvm_template_checkbox.setChecked(
- not vm.template_for_dispvms)
+ settings_window.dvm_template_checkbox.setChecked(not vm.template_for_dispvms)
+
+ assert (
+ settings_window.preload_dispvm.isEnabled()
+ == settings_window.dvm_template_checkbox.isChecked()
+ )
expected_calls = [
- (vm.name, 'admin.vm.property.Set', 'template_for_dispvms',
- str(not vm.template_for_dispvms).encode())
+ (
+ vm.name,
+ "admin.vm.property.Set",
+ "template_for_dispvms",
+ str(not vm.template_for_dispvms).encode(),
+ )
]
if vm.template_for_dispvms:
# remove existis menus
- expected_calls.append((vm.name, 'admin.vm.feature.Remove',
- 'appmenus-dispvm', None))
+ expected_calls.append(
+ (vm.name, "admin.vm.feature.Remove", "appmenus-dispvm", None)
+ )
else:
- expected_calls.append((vm.name, 'admin.vm.feature.Set',
- 'appmenus-dispvm', b'1'))
+ expected_calls.append(
+ (vm.name, "admin.vm.feature.Set", "appmenus-dispvm", b"1")
+ )
for call in expected_calls:
assert call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[call] = b"0\x00"
settings_window.accept()
@@ -846,12 +980,16 @@ def test_207_def_dispvm(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
- _select_item(settings_window.default_dispvm, 'test-vm-set')
+ _select_item(settings_window.default_dispvm, "test-vm-set")
- expected_call = (vm.name, 'admin.vm.property.Set', 'default_dispvm',
- b'test-vm-set')
+ expected_call = (
+ vm.name,
+ "admin.vm.property.Set",
+ "default_dispvm",
+ b"test-vm-set",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -866,17 +1004,21 @@ def test_208_fullscreen(settings_fixture):
assert "current" in settings_window.allow_fullscreen.currentText()
- if 'gui-allow-fullscreen' not in vm.features:
+ if "gui-allow-fullscreen" not in vm.features:
assert "default" in settings_window.allow_fullscreen.currentText()
- if vm.features.get('gui-allow-fullscreen', None) == '1':
- assert 'allow' in settings_window.allow_fullscreen.currentText()
+ if vm.features.get("gui-allow-fullscreen", None) == "1":
+ assert "allow" in settings_window.allow_fullscreen.currentText()
_select_item(settings_window.allow_fullscreen, "disallow")
- expected_call = (vm.name, 'admin.vm.feature.Set', 'gui-allow-fullscreen',
- b'')
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Set",
+ "gui-allow-fullscreen",
+ b"",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -891,17 +1033,21 @@ def test_209_utf8_titles(settings_fixture):
assert "current" in settings_window.allow_utf8.currentText()
- if 'gui-allow-utf8-titles' not in vm.features:
+ if "gui-allow-utf8-titles" not in vm.features:
assert "default" in settings_window.allow_utf8.currentText()
- if vm.features.get('gui-allow-utf8-titles', None) == '1':
- assert 'allow' in settings_window.allow_utf8.currentText()
+ if vm.features.get("gui-allow-utf8-titles", None) == "1":
+ assert "allow" in settings_window.allow_utf8.currentText()
_select_item(settings_window.allow_utf8, "disallow")
- expected_call = (vm.name, 'admin.vm.feature.Set', 'gui-allow-utf8-titles',
- b'')
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Set",
+ "gui-allow-utf8-titles",
+ b"",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -918,15 +1064,14 @@ def test_210_kernel(settings_fixture):
_select_item(settings_window.kernel, "misc")
- if not vm.property_is_default('kernel'):
+ if not vm.property_is_default("kernel"):
_select_item(settings_window.kernel, "default")
- expected_call = (vm.name, 'admin.vm.property.Reset', 'kernel', None)
+ expected_call = (vm.name, "admin.vm.property.Reset", "kernel", None)
else:
_select_item(settings_window.kernel, "misc")
- expected_call = (vm.name, 'admin.vm.property.Set', 'kernel',
- b'misc')
+ expected_call = (vm.name, "admin.vm.property.Set", "kernel", b"misc")
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -941,23 +1086,23 @@ def test_211_virtmode(settings_fixture):
assert str(vm.virt_mode).upper() in settings_window.virt_mode.currentText()
- if vm.virt_mode == 'pvh':
- _select_item(settings_window.virt_mode, 'HVM')
- expected_call = (vm.name, 'admin.vm.property.Set', 'virt_mode', b'hvm')
+ if vm.virt_mode == "pvh":
+ _select_item(settings_window.virt_mode, "HVM")
+ expected_call = (vm.name, "admin.vm.property.Set", "virt_mode", b"hvm")
else:
- _select_item(settings_window.virt_mode, 'PV', match_strict=True)
- expected_call = (vm.name, 'admin.vm.property.Set', 'virt_mode', b'pv')
+ _select_item(settings_window.virt_mode, "PV", match_strict=True)
+ expected_call = (vm.name, "admin.vm.property.Set", "virt_mode", b"pv")
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
assert expected_call in settings_window.qubesapp.actual_calls
-@mock.patch('qubesadmin.tools.qvm_start.main')
-@mock.patch('qubesmanager.bootfromdevice.VMBootFromDeviceWindow')
+@mock.patch("qubesadmin.tools.qvm_start.main")
+@mock.patch("qubesmanager.bootfromdevice.VMBootFromDeviceWindow")
@check_errors
@pytest.mark.parametrize("settings_fixture", TEST_VMS, indirect=True)
def test_212_boot_from_device(mock_boot, mock_start, settings_fixture):
@@ -969,10 +1114,14 @@ def test_212_boot_from_device(mock_boot, mock_start, settings_fixture):
settings_window.boot_from_device_button.click()
mock_boot.assert_called_with(
- vm=vm.name, qapp=settings_window.qapp,
- qubesapp=settings_window.qubesapp, parent=settings_window)
+ vm=vm.name,
+ qapp=settings_window.qapp,
+ qubesapp=settings_window.qubesapp,
+ parent=settings_window,
+ )
+
+ mock_start.assert_called_with(["--cdrom", mock.ANY, vm.name])
- mock_start.assert_called_with(['--cdrom', mock.ANY, vm.name])
@check_errors
@pytest.mark.parametrize("settings_fixture", ["fedora-36-bootmodes"], indirect=True)
@@ -990,30 +1139,39 @@ def test_213_bootmode_template(settings_fixture):
assert settings_window.bootmode_kernel_opts.text() == ""
_select_item(settings_window.bootmode, "Mode One")
assert settings_window.bootmode_kernel_opts.text() == "mode1kern"
- with mock.patch('qubesadmin.base.PropertyHolder.property_get_default',
- return_value='mode1'):
+ with mock.patch(
+ "qubesadmin.base.PropertyHolder.property_get_default",
+ return_value="mode1",
+ ):
_select_item(settings_window.bootmode, "default")
assert settings_window.bootmode_kernel_opts.text() == "mode1kern"
_select_item(settings_window.bootmode, "mode2")
_select_item(settings_window.appvm_default_bootmode, "Mode One")
- expected_call_bm = (vm_name, 'admin.vm.property.Set', 'bootmode', b'mode2')
+ expected_call_bm = (vm_name, "admin.vm.property.Set", "bootmode", b"mode2")
assert expected_call_bm not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call_bm] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call_bm] = b"0\x00"
- expected_call_adbm = (vm_name, 'admin.vm.property.Set', \
- 'appvm_default_bootmode', b'mode1')
+ expected_call_adbm = (
+ vm_name,
+ "admin.vm.property.Set",
+ "appvm_default_bootmode",
+ b"mode1",
+ )
assert expected_call_adbm not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call_adbm] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call_adbm] = b"0\x00"
settings_window.accept()
- assert expected_call_bm in settings_window.qubesapp.actual_calls, \
- "Boot mode not changed"
- assert expected_call_adbm in settings_window.qubesapp.actual_calls, \
- "AppVM default boot mode not changed"
+ assert (
+ expected_call_bm in settings_window.qubesapp.actual_calls
+ ), "Boot mode not changed"
+ assert (
+ expected_call_adbm in settings_window.qubesapp.actual_calls
+ ), "AppVM default boot mode not changed"
+
@check_errors
@pytest.mark.parametrize("settings_fixture", ["test-vm-bootmodes"], indirect=True)
@@ -1031,17 +1189,21 @@ def test_214_bootmode_appvm(settings_fixture):
assert settings_window.bootmode_kernel_opts.text() == "mode2kern1 mode2kern2"
_select_item(settings_window.bootmode, "Mode One")
- expected_call = (vm_name, 'admin.vm.property.Set', 'bootmode', b'mode1')
+ expected_call = (vm_name, "admin.vm.property.Set", "bootmode", b"mode1")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Boot mode not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Boot mode not changed"
+
@check_errors
-@pytest.mark.parametrize("settings_fixture", ["test-vm-bootmodes-nondefault"], indirect=True)
+@pytest.mark.parametrize(
+ "settings_fixture", ["test-vm-bootmodes-nondefault"], indirect=True
+)
def test_215_bootmode_appvm_nondefault(settings_fixture):
settings_window, page, vm_name = settings_fixture
@@ -1057,14 +1219,15 @@ def test_215_bootmode_appvm_nondefault(settings_fixture):
assert settings_window.bootmode_kernel_opts.text() == "mode2kern1 mode2kern2"
_select_item(settings_window.bootmode, "Mode One")
- expected_call = (vm_name, 'admin.vm.property.Set', 'bootmode', b'mode1')
+ expected_call = (vm_name, "admin.vm.property.Set", "bootmode", b"mode1")
assert expected_call not in settings_window.qubesapp.expected_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
- assert expected_call in settings_window.qubesapp.actual_calls, \
- "Boot mode not changed"
+ assert (
+ expected_call in settings_window.qubesapp.actual_calls
+ ), "Boot mode not changed"
@check_errors
@@ -1104,6 +1267,7 @@ def test_213_prohibit_start(settings_fixture):
# FIREWALL TAB
+
@check_errors
@pytest.mark.parametrize("settings_fixture", ["test-blue"], indirect=True)
def test_300_firewall_start_limiting(settings_fixture):
@@ -1118,11 +1282,13 @@ def test_300_firewall_start_limiting(settings_fixture):
settings_window.policy_deny_radio_button.setChecked(True)
expected_call = (
- 'test-blue', 'admin.vm.firewall.Set', None,
- b'action=accept specialtarget=dns\naction=accept '
- b'proto=icmp\naction=drop\n')
+ "test-blue",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept specialtarget=dns\naction=accept " b"proto=icmp\naction=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1144,10 +1310,13 @@ def test_301_firewall_unlimit(settings_fixture):
settings_window.policy_allow_radio_button.setChecked(True)
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept dsthost=qubes-os.org\naction=accept\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept dsthost=qubes-os.org\naction=accept\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1165,16 +1334,17 @@ def test_302_firewall_remove_rule(settings_fixture):
assert settings_window.policy_allow_radio_button.isEnabled()
assert settings_window.policy_deny_radio_button.isChecked()
- settings_window.rulesTreeView.setCurrentIndex(
- settings_window.fw_model.index(0, 0))
+ settings_window.rulesTreeView.setCurrentIndex(settings_window.fw_model.index(0, 0))
settings_window.delete_rule_button.click()
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept specialtarget=dns\naction=accept '
- b'proto=icmp\naction=drop\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept specialtarget=dns\naction=accept " b"proto=icmp\naction=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1193,20 +1363,23 @@ def test_303_firewall_add_rule(settings_fixture):
assert settings_window.policy_deny_radio_button.isChecked()
settings_window.new_rule_button.click()
- settings_window.fw_model.current_dialog.addressComboBox.setCurrentText(
- "test_stuff")
+ settings_window.fw_model.current_dialog.addressComboBox.setCurrentText("test_stuff")
settings_window.fw_model.current_dialog.buttonBox.button(
- QtWidgets.QDialogButtonBox.StandardButton.Ok).click()
+ QtWidgets.QDialogButtonBox.StandardButton.Ok
+ ).click()
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept dsthost=qubes-os.org\n'
- b'action=accept dsthost=test_stuff\n'
- b'action=accept specialtarget=dns\n'
- b'action=accept proto=icmp\n'
- b'action=drop\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept dsthost=qubes-os.org\n"
+ b"action=accept dsthost=test_stuff\n"
+ b"action=accept specialtarget=dns\n"
+ b"action=accept proto=icmp\n"
+ b"action=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1225,23 +1398,25 @@ def test_304_firewall_add_rule_complex(settings_fixture):
assert settings_window.policy_deny_radio_button.isChecked()
settings_window.new_rule_button.click()
- settings_window.fw_model.current_dialog.addressComboBox.setCurrentText(
- "test_stuff")
+ settings_window.fw_model.current_dialog.addressComboBox.setCurrentText("test_stuff")
settings_window.fw_model.current_dialog.udp_radio.setChecked(True)
- _select_item(settings_window.fw_model.current_dialog.serviceComboBox,
- "http")
+ _select_item(settings_window.fw_model.current_dialog.serviceComboBox, "http")
settings_window.fw_model.current_dialog.buttonBox.button(
- QtWidgets.QDialogButtonBox.StandardButton.Ok).click()
+ QtWidgets.QDialogButtonBox.StandardButton.Ok
+ ).click()
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept dsthost=qubes-os.org\n'
- b'action=accept proto=udp dsthost=test_stuff dstports=80-80\n'
- b'action=accept specialtarget=dns\n'
- b'action=accept proto=icmp\n'
- b'action=drop\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept dsthost=qubes-os.org\n"
+ b"action=accept proto=udp dsthost=test_stuff dstports=80-80\n"
+ b"action=accept specialtarget=dns\n"
+ b"action=accept proto=icmp\n"
+ b"action=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1259,23 +1434,25 @@ def test_305_firewall_edit_rule(settings_fixture):
assert settings_window.policy_allow_radio_button.isEnabled()
assert settings_window.policy_deny_radio_button.isChecked()
- settings_window.rulesTreeView.setCurrentIndex(
- settings_window.fw_model.index(0, 0))
+ settings_window.rulesTreeView.setCurrentIndex(settings_window.fw_model.index(0, 0))
settings_window.edit_rule_button.click()
settings_window.fw_model.current_dialog.tcp_radio.setChecked(True)
- _select_item(settings_window.fw_model.current_dialog.serviceComboBox,
- "printer")
+ _select_item(settings_window.fw_model.current_dialog.serviceComboBox, "printer")
settings_window.fw_model.current_dialog.buttonBox.button(
- QtWidgets.QDialogButtonBox.StandardButton.Ok).click()
+ QtWidgets.QDialogButtonBox.StandardButton.Ok
+ ).click()
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept proto=tcp dsthost=qubes-os.org dstports=515-515\n'
- b'action=accept specialtarget=dns\naction=accept '
- b'proto=icmp\naction=drop\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept proto=tcp dsthost=qubes-os.org dstports=515-515\n"
+ b"action=accept specialtarget=dns\naction=accept "
+ b"proto=icmp\naction=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1296,17 +1473,21 @@ def test_306_firewall_unlimit(settings_fixture):
settings_window.temp_full_access.setChecked(True)
# add 5 minutes to now
- expiration_date = str((int(datetime.datetime.now().strftime(
- "%s")) + 5 * 60)).encode()
+ expiration_date = str(
+ (int(datetime.datetime.now().strftime("%s")) + 5 * 60)
+ ).encode()
expected_call = (
- 'test-vm-set', 'admin.vm.firewall.Set', None,
- b'action=accept dsthost=qubes-os.org\n'
- b'action=accept expire=' + expiration_date + b'\n'
- b'action=accept specialtarget=dns\naction=accept '
- b'proto=icmp\naction=drop\n')
+ "test-vm-set",
+ "admin.vm.firewall.Set",
+ None,
+ b"action=accept dsthost=qubes-os.org\n"
+ b"action=accept expire=" + expiration_date + b"\n"
+ b"action=accept specialtarget=dns\naction=accept "
+ b"proto=icmp\naction=drop\n",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1314,7 +1495,7 @@ def test_306_firewall_unlimit(settings_fixture):
@check_errors
-@mock.patch('subprocess.check_output')
+@mock.patch("subprocess.check_output")
def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
# this test is supposed to check if the settings open even when there is
# an unlimited FW access set
@@ -1322,27 +1503,30 @@ def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
mock_subprocess.result = []
# add 2 minutes to now
- expiration_date = str((int(datetime.datetime.now().strftime(
- "%s")) + 2 * 60))
+ expiration_date = str((int(datetime.datetime.now().strftime("%s")) + 2 * 60))
fw_rules = [
{"action": "accept", "expire": expiration_date},
{"action": "accept", "specialtarget": "dns"},
{"action": "accept", "proto": "icmp"},
- {"action": "drop"}
+ {"action": "drop"},
]
- test_qubes_app._qubes['test-vm-fw'] = MockQube(
- name="test-vm-fw", qapp=test_qubes_app, label="green",
- firewall_rules=fw_rules
+ test_qubes_app._qubes["test-vm-fw"] = MockQube(
+ name="test-vm-fw",
+ qapp=test_qubes_app,
+ label="green",
+ firewall_rules=fw_rules,
+ )
+ expected_call = ("test-vm-fw", "admin.vm.notes.Get", None, None)
+ test_qubes_app.expected_calls[expected_call] = (
+ "2\0QubesNotesException\0\0Notes not available!\0"
)
- expected_call = ("test-vm-fw", 'admin.vm.notes.Get', None, None)
- test_qubes_app.expected_calls[expected_call] = \
- '2\0QubesNotesException\0\0Notes not available!\0'
test_qubes_app.update_vm_calls()
settings_window = vm_settings.VMSettingsWindow(
- 'test-vm-fw', 'basic', qapp, test_qubes_app)
+ "test-vm-fw", "basic", qapp, test_qubes_app
+ )
assert settings_window.policy_deny_radio_button.isEnabled()
assert settings_window.policy_allow_radio_button.isEnabled()
@@ -1354,89 +1538,89 @@ def test_307_open_with_limit(mock_subprocess, qapp, test_qubes_app):
@check_errors
-@pytest.mark.parametrize("settings_fixture",
- [{'vm': 'vault', 'page': 'firewall'}],
- indirect=True)
+@pytest.mark.parametrize(
+ "settings_fixture", [{"vm": "vault", "page": "firewall"}], indirect=True
+)
def test_308_firewall_none(settings_fixture):
settings_window, page, vm_name = settings_fixture
assert settings_window.no_netvm_label.isVisibleTo(settings_window)
- _select_item(settings_window.netVM, 'sys-net')
+ _select_item(settings_window.netVM, "sys-net")
assert not settings_window.no_netvm_label.isVisibleTo(settings_window)
- _select_item(settings_window.netVM, 'none')
+ _select_item(settings_window.netVM, "none")
assert settings_window.no_netvm_label.isVisibleTo(settings_window)
@check_errors
-@pytest.mark.parametrize("settings_fixture",
- [{'vm': 'vault', 'page': 'firewall'}],
- indirect=True)
+@pytest.mark.parametrize(
+ "settings_fixture", [{"vm": "vault", "page": "firewall"}], indirect=True
+)
def test_309_firewall_warn(settings_fixture):
settings_window, page, vm_name = settings_fixture
assert not settings_window.sysnet_warning_label.isVisibleTo(settings_window)
- settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices[
- 'advanced'])
+ settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices["advanced"])
settings_window.provides_network_checkbox.setChecked(True)
- settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices[
- 'firewall'])
+ settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices["firewall"])
assert settings_window.sysnet_warning_label.isVisibleTo(settings_window)
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-blue'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-blue"], indirect=True)
def test_310_stupid_netvm(settings_fixture):
settings_window, page, vm_name = settings_fixture
- assert not settings_window.netvm_no_firewall_label.isVisibleTo(
- settings_window)
+ assert not settings_window.netvm_no_firewall_label.isVisibleTo(settings_window)
- _select_item(settings_window.netVM, 'test-vm-set')
+ _select_item(settings_window.netVM, "test-vm-set")
- settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices[
- 'firewall'])
+ settings_window.tabWidget.setCurrentIndex(settings_window.tabs_indices["firewall"])
assert settings_window.netvm_no_firewall_label.isVisibleTo(settings_window)
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_400_services(settings_fixture):
settings_window, page, vm_name = settings_fixture
- enabled_services = [settings_window.services_list.item(i).text() for i in
- range(settings_window.services_list.count())]
+ enabled_services = [
+ settings_window.services_list.item(i).text()
+ for i in range(settings_window.services_list.count())
+ ]
available_services = []
for i in range(settings_window.service_line_edit.count()):
- item_text = str(settings_window.service_line_edit.itemData(i,
- QtCore.Qt.ItemDataRole.DisplayRole))
+ item_text = str(
+ settings_window.service_line_edit.itemData(
+ i, QtCore.Qt.ItemDataRole.DisplayRole
+ )
+ )
available_services.append(item_text)
- assert enabled_services == ['qubes-u2f-proxy']
+ assert enabled_services == ["qubes-u2f-proxy"]
assert sorted(available_services) == sorted(
- ['', 'qubes-u2f-proxy', 'clocksync', '(custom...)'])
+ ["", "qubes-u2f-proxy", "clocksync", "(custom...)"]
+ )
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_401_services_remove(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.services_list.count()):
item_text = settings_window.services_list.item(i).text()
- if item_text == 'qubes-u2f-proxy':
+ if item_text == "qubes-u2f-proxy":
settings_window.services_list.setCurrentRow(i)
break
else:
@@ -1444,10 +1628,14 @@ def test_401_services_remove(settings_fixture):
settings_window.remove_srv_button.click()
- expected_call = (vm.name, 'admin.vm.feature.Remove',
- 'service.qubes-u2f-proxy', None)
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Remove",
+ "service.qubes-u2f-proxy",
+ None,
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1455,24 +1643,25 @@ def test_401_services_remove(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_402_services_add(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.service_line_edit.count()):
- item_text = str(settings_window.service_line_edit.itemData(i,
- QtCore.Qt.ItemDataRole.DisplayRole))
- if item_text == 'clocksync':
+ item_text = str(
+ settings_window.service_line_edit.itemData(
+ i, QtCore.Qt.ItemDataRole.DisplayRole
+ )
+ )
+ if item_text == "clocksync":
settings_window.service_line_edit.setCurrentIndex(i)
settings_window.add_srv_button.click()
- expected_call = (vm.name, 'admin.vm.feature.Set',
- 'service.clocksync', b'1')
+ expected_call = (vm.name, "admin.vm.feature.Set", "service.clocksync", b"1")
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1480,26 +1669,34 @@ def test_402_services_add(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_403_services_add_custom(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.service_line_edit.count()):
- item_text = str(settings_window.service_line_edit.itemData(i,
- QtCore.Qt.ItemDataRole.DisplayRole))
- if 'custom' in item_text:
+ item_text = str(
+ settings_window.service_line_edit.itemData(
+ i, QtCore.Qt.ItemDataRole.DisplayRole
+ )
+ )
+ if "custom" in item_text:
settings_window.service_line_edit.setCurrentIndex(i)
- with mock.patch('PyQt6.QtWidgets.QInputDialog.getText',
- return_value=('shutdown-idle', True)):
+ with mock.patch(
+ "PyQt6.QtWidgets.QInputDialog.getText",
+ return_value=("shutdown-idle", True),
+ ):
settings_window.add_srv_button.click()
- expected_call = (vm.name, 'admin.vm.feature.Set',
- 'service.shutdown-idle', b'1')
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Set",
+ "service.shutdown-idle",
+ b"1",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1507,24 +1704,27 @@ def test_403_services_add_custom(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_404_services_disable(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.services_list.count()):
item = settings_window.services_list.item(i)
- if item.text() == 'qubes-u2f-proxy':
+ if item.text() == "qubes-u2f-proxy":
item.setCheckState(QtCore.Qt.CheckState.Unchecked)
break
else:
assert False, "Failed to find service"
- expected_call = (vm.name, 'admin.vm.feature.Set',
- 'service.qubes-u2f-proxy', b'')
+ expected_call = (
+ vm.name,
+ "admin.vm.feature.Set",
+ "service.qubes-u2f-proxy",
+ b"",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1532,55 +1732,52 @@ def test_404_services_disable(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-red'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-red"], indirect=True)
def test_500_applications_list(settings_fixture):
settings_window, page, vm_name = settings_fixture
available = []
selected = []
for i in range(settings_window.app_list.available_list.count()):
- available.append(
- settings_window.app_list.available_list.item(i).text())
+ available.append(settings_window.app_list.available_list.item(i).text())
for i in range(settings_window.app_list.selected_list.count()):
- selected.append(
- settings_window.app_list.selected_list.item(i).text())
+ selected.append(settings_window.app_list.selected_list.item(i).text())
assert not selected
- assert available == ['Test App', 'Test2 App', 'Test3 App']
+ assert available == ["Test App", "Test2 App", "Test3 App"]
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_501_applications_list_existing(settings_fixture):
settings_window, page, vm_name = settings_fixture
available = []
selected = []
for i in range(settings_window.app_list.available_list.count()):
- available.append(
- settings_window.app_list.available_list.item(i).text())
+ available.append(settings_window.app_list.available_list.item(i).text())
for i in range(settings_window.app_list.selected_list.count()):
- selected.append(
- settings_window.app_list.selected_list.item(i).text())
+ selected.append(settings_window.app_list.selected_list.item(i).text())
# some apps are present, some are missing
- assert available == ['My VM app', 'Test2 App', 'Test3 App']
- assert selected == ['Application missing in template! (missing.desktop)',
- 'Test App']
+ assert available == ["My VM app", "Test2 App", "Test3 App"]
+ assert selected == [
+ "Application missing in template! (missing.desktop)",
+ "Test App",
+ ]
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-red',
- 'test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-red", "test-vm-set"], indirect=True)
def test_502_application_add(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.app_list.available_list.count()):
item = settings_window.app_list.available_list.item(i)
- if item.text() == 'Test3 App':
+ if item.text() == "Test3 App":
item.setSelected(True)
break
else:
@@ -1588,17 +1785,23 @@ def test_502_application_add(settings_fixture):
settings_window.app_list.add_selected_button.click()
- if vm.name == 'test-vm-set':
+ if vm.name == "test-vm-set":
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'missing.desktop test.desktop test3.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"missing.desktop test.desktop test3.desktop",
+ )
else:
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'test3.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"test3.desktop",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1606,14 +1809,14 @@ def test_502_application_add(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_503_application_remove(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.app_list.selected_list.count()):
item = settings_window.app_list.selected_list.item(i)
- if item.text() == 'Test App':
+ if item.text() == "Test App":
item.setSelected(True)
break
else:
@@ -1622,10 +1825,13 @@ def test_503_application_remove(settings_fixture):
settings_window.app_list.remove_selected_button.click()
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'missing.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"missing.desktop",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1633,7 +1839,7 @@ def test_503_application_remove(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_504_application_remove_missing(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
@@ -1649,10 +1855,13 @@ def test_504_application_remove_missing(settings_fixture):
settings_window.app_list.remove_selected_button.click()
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'test.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"test.desktop",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1660,26 +1869,31 @@ def test_504_application_remove_missing(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-red',
- 'test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-red", "test-vm-set"], indirect=True)
def test_505_application_add_all(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
settings_window.app_list.add_all_button.click()
- if vm.name == 'test-vm-set':
+ if vm.name == "test-vm-set":
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'missing.desktop myvm.desktop test.desktop '
- b'test2.desktop test3.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"missing.desktop myvm.desktop test.desktop "
+ b"test2.desktop test3.desktop",
+ )
else:
expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items',
- b'test.desktop test2.desktop test3.desktop')
+ vm.name,
+ "admin.vm.feature.Set",
+ "menu-items",
+ b"test.desktop test2.desktop test3.desktop",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1687,23 +1901,21 @@ def test_505_application_add_all(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-red',
- 'test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-red", "test-vm-set"], indirect=True)
def test_506_application_remove_all(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
settings_window.app_list.remove_all_button.click()
- expected_call = (
- vm.name, 'admin.vm.feature.Set', 'menu-items', b'')
+ expected_call = (vm.name, "admin.vm.feature.Set", "menu-items", b"")
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
- if vm.name == 'test-vm-set':
+ if vm.name == "test-vm-set":
assert expected_call in settings_window.qubesapp.actual_calls
else:
# that VM had no apps to begin with
@@ -1711,7 +1923,7 @@ def test_506_application_remove_all(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_600_devices(settings_fixture):
settings_window, page, vm_name = settings_fixture
@@ -1724,14 +1936,14 @@ def test_600_devices(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-vm-set'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-vm-set"], indirect=True)
def test_601_device_add(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
for i in range(settings_window.dev_list.available_list.count()):
item = settings_window.dev_list.available_list.item(i)
- if 'USB' in item.text():
+ if "USB" in item.text():
item.setSelected(True)
break
else:
@@ -1740,12 +1952,15 @@ def test_601_device_add(settings_fixture):
settings_window.dev_list.add_selected_button.click()
expected_call = (
- vm.name, 'admin.vm.device.pci.Assign', 'dom0+00_03.0:*',
+ vm.name,
+ "admin.vm.device.pci.Assign",
+ "dom0+00_03.0:*",
b"device_id='*' port_id='00_03.0' devclass='pci' "
b"backend_domain='dom0' mode='required' "
- b"frontend_domain='test-vm-set'")
+ b"frontend_domain='test-vm-set'",
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1753,7 +1968,7 @@ def test_601_device_add(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-pci-dev'], indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-pci-dev"], indirect=True)
def test_602_device_remove(settings_fixture):
settings_window, page, vm_name = settings_fixture
vm = settings_window.qubesapp.domains[vm_name]
@@ -1775,10 +1990,14 @@ def test_602_device_remove(settings_fixture):
settings_window.dev_list.remove_selected_button.click()
- expected_call = (vm.name, 'admin.vm.device.pci.Unassign',
- 'dom0+00_04.3:0x8008:0x1234::p040000', None)
+ expected_call = (
+ vm.name,
+ "admin.vm.device.pci.Unassign",
+ "dom0+00_04.3:0x8008:0x1234::p040000",
+ None,
+ )
assert expected_call not in settings_window.qubesapp.actual_calls
- settings_window.qubesapp.expected_calls[expected_call] = b'0\x00'
+ settings_window.qubesapp.expected_calls[expected_call] = b"0\x00"
settings_window.accept()
@@ -1786,18 +2005,18 @@ def test_602_device_remove(settings_fixture):
@check_errors
-@pytest.mark.parametrize("settings_fixture", ['test-pci-dev'],
- indirect=True)
+@pytest.mark.parametrize("settings_fixture", ["test-pci-dev"], indirect=True)
def test_603_virtmode_limitation(settings_fixture):
settings_window, page, vm_name = settings_fixture
available_virtmodes = []
for i in range(settings_window.virt_mode.count()):
- item_text = str(settings_window.virt_mode.itemData(
- i, QtCore.Qt.ItemDataRole.DisplayRole))
+ item_text = str(
+ settings_window.virt_mode.itemData(i, QtCore.Qt.ItemDataRole.DisplayRole)
+ )
available_virtmodes.append(item_text)
- assert len(available_virtmodes) == 3 # HVM, PV, default
- assert 'PVH' not in available_virtmodes
- assert 'HVM (current)' in available_virtmodes
- assert 'PV' in available_virtmodes
+ assert len(available_virtmodes) == 3 # HVM, PV, default
+ assert "PVH" not in available_virtmodes
+ assert "HVM (current)" in available_virtmodes
+ assert "PV" in available_virtmodes
diff --git a/ui/settingsdlg.ui b/ui/settingsdlg.ui
index ea986609..06970737 100644
--- a/ui/settingsdlg.ui
+++ b/ui/settingsdlg.ui
@@ -742,6 +742,13 @@ border-width: 1px;
15
+ -
+
+
+ Run in debug mode
+
+
+
-
-
@@ -780,40 +787,143 @@ border-width: 1px;
- -
-
+
-
+
+
+ <html><head/><body><p>Configure how many disposables this template must preload.</p></body></html>
+
- Boot qube from DISC or block device
+ Preload disposables:
- -
-
-
-
-
-
- Windows (with Qubes Windows Tools installed) only.
-The qube must be running to enable seamless mode. This setting is not persistent.
-
-
- Enable seamless mode
-
-
-
- -
-
-
- Windows (with Qubes Windows Tools installed) only.
-The qube must be running to disable seamless mode. This setting is not persistent.
-
-
- Disable seamless mode
-
-
-
-
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
+
+ 50
+
+
-
+
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+ 239
+ 41
+ 41
+
+
+
+
+
+
+
+
+ 190
+ 190
+ 190
+
+
+
+
+
+
+ 190
+ 190
+ 190
+
+
+
+
+
+
+ 0
+ 0
+ 0
+
+
+
+
+
+
+
+
+ true
+ true
+
+
+
+ This qube is the default disposable template the global preload feature is set, therefore, it will honor the Global Config preference until the feature is deleted.
+
+
+ Qt::AlignJustify|Qt::AlignVCenter
+
+
+ true
+
+
+
+ -
-
@@ -843,13 +953,39 @@ The qube must be running to disable seamless mode. This setting is not persisten
- -
-
+
-
+
- Run in debug mode
+ Boot qube from DISC or block device
+ -
+
+
-
+
+
+ Windows (with Qubes Windows Tools installed) only.
+The qube must be running to enable seamless mode. This setting is not persistent.
+
+
+ Enable seamless mode
+
+
+
+ -
+
+
+ Windows (with Qubes Windows Tools installed) only.
+The qube must be running to disable seamless mode. This setting is not persistent.
+
+
+ Disable seamless mode
+
+
+
+
+
@@ -1933,6 +2069,7 @@ For user reference only.
run_in_debug_mode
provides_network_checkbox
dvm_template_checkbox
+ preload_dispvm
default_dispvm
boot_from_device_button
seamless_on_button