Global Settings now can function with partial permissions
Unreadable properties/features will be disabled, the tool will start even if it can access nothing or almost nothing, and errors on settings features/properties will now be communicated to the user.
This commit is contained in:
		
							parent
							
								
									1f933b775a
								
							
						
					
					
						commit
						7cbc7d9db1
					
				| @ -25,6 +25,7 @@ import subprocess | |||||||
| from PyQt5 import QtWidgets, QtCore, QtGui  # pylint: disable=import-error | from PyQt5 import QtWidgets, QtCore, QtGui  # pylint: disable=import-error | ||||||
| 
 | 
 | ||||||
| from qubesadmin.utils import parse_size | from qubesadmin.utils import parse_size | ||||||
|  | from qubesadmin import exc | ||||||
| 
 | 
 | ||||||
| from . import ui_globalsettingsdlg  # pylint: disable=no-name-in-module | from . import ui_globalsettingsdlg  # pylint: disable=no-name-in-module | ||||||
| from . import utils | from . import utils | ||||||
| @ -83,6 +84,8 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|         self.__init_updates__() |         self.__init_updates__() | ||||||
|         self.__init_gui_defaults() |         self.__init_gui_defaults() | ||||||
| 
 | 
 | ||||||
|  |         self.errors = [] | ||||||
|  | 
 | ||||||
|     def setup_application(self): |     def setup_application(self): | ||||||
|         self.app.setApplicationName(self.tr("Qubes Global Settings")) |         self.app.setApplicationName(self.tr("Qubes Global Settings")) | ||||||
|         self.app.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager")) |         self.app.setWindowIcon(QtGui.QIcon.fromTheme("qubes-manager")) | ||||||
| @ -112,7 +115,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|         utils.initialize_widget_with_vms( |         utils.initialize_widget_with_vms( | ||||||
|             widget=self.default_netvm_combo, |             widget=self.default_netvm_combo, | ||||||
|             qubes_app=self.qubes_app, |             qubes_app=self.qubes_app, | ||||||
|             filter_function=(lambda vm: vm.provides_network), |             filter_function=(lambda vm: getattr(vm, 'provides_network', False)), | ||||||
|             allow_none=True, |             allow_none=True, | ||||||
|             holder=self.qubes_app, |             holder=self.qubes_app, | ||||||
|             property_name="default_netvm" |             property_name="default_netvm" | ||||||
| @ -142,39 +145,67 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|     def __apply_system_defaults__(self): |     def __apply_system_defaults__(self): | ||||||
|         # updatevm |         # updatevm | ||||||
|         if utils.did_widget_selection_change(self.update_vm_combo): |         if utils.did_widget_selection_change(self.update_vm_combo): | ||||||
|             self.qubes_app.updatevm = self.update_vm_combo.currentData() |             try: | ||||||
|  |                 self.qubes_app.updatevm = self.update_vm_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set UpdateVM due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|         # clockvm |         # clockvm | ||||||
|         if utils.did_widget_selection_change(self.clock_vm_combo): |         if utils.did_widget_selection_change(self.clock_vm_combo): | ||||||
|             self.qubes_app.clockvm = self.clock_vm_combo.currentData() |             try: | ||||||
|  |                 self.qubes_app.clockvm = self.clock_vm_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set ClockVM due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|         # default netvm |         # default netvm | ||||||
|         if utils.did_widget_selection_change(self.default_netvm_combo): |         if utils.did_widget_selection_change(self.default_netvm_combo): | ||||||
|             self.qubes_app.default_netvm = \ |             try: | ||||||
|                 self.default_netvm_combo.currentData() |                 self.qubes_app.default_netvm = \ | ||||||
|  |                     self.default_netvm_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set Default NetVM due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|         # default template |         # default template | ||||||
|         if utils.did_widget_selection_change(self.default_template_combo): |         if utils.did_widget_selection_change(self.default_template_combo): | ||||||
|             self.qubes_app.default_template = \ |             try: | ||||||
|                 self.default_template_combo.currentData() |                 self.qubes_app.default_template = \ | ||||||
|  |                     self.default_template_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set Default Template due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|         # default_dispvm |         # default_dispvm | ||||||
|         if utils.did_widget_selection_change(self.default_dispvm_combo): |         if utils.did_widget_selection_change(self.default_dispvm_combo): | ||||||
|             self.qubes_app.default_dispvm = \ |             try: | ||||||
|                 self.default_dispvm_combo.currentData() |                 self.qubes_app.default_dispvm = \ | ||||||
|  |                     self.default_dispvm_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set Default DispVM due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|     def __init_kernel_defaults__(self): |     def __init_kernel_defaults__(self): | ||||||
|         utils.initialize_widget_with_kernels( |         try: | ||||||
|             widget=self.default_kernel_combo, |             utils.initialize_widget_with_kernels( | ||||||
|             qubes_app=self.qubes_app, |                 widget=self.default_kernel_combo, | ||||||
|             allow_none=True, |                 qubes_app=self.qubes_app, | ||||||
|             holder=self.qubes_app, |                 allow_none=True, | ||||||
|             property_name='default_kernel') |                 holder=self.qubes_app, | ||||||
|  |                 property_name='default_kernel') | ||||||
|  |         except exc.QubesPropertyAccessError: | ||||||
|  |             self.default_kernel_combo.clear() | ||||||
|  |             self.default_kernel_combo.setEnabled(False) | ||||||
| 
 | 
 | ||||||
|     def __apply_kernel_defaults__(self): |     def __apply_kernel_defaults__(self): | ||||||
|         if utils.did_widget_selection_change(self.default_kernel_combo): |         if utils.did_widget_selection_change(self.default_kernel_combo): | ||||||
|             self.qubes_app.default_kernel = \ |             try: | ||||||
|                 self.default_kernel_combo.currentData() |                 self.qubes_app.default_kernel = \ | ||||||
|  |                     self.default_kernel_combo.currentData() | ||||||
|  |             except exc.QubesException as ex: | ||||||
|  |                 self.errors.append( | ||||||
|  |                     "Failed to set Default Kernel due to {}".format(str(ex))) | ||||||
| 
 | 
 | ||||||
|     def __init_gui_defaults(self): |     def __init_gui_defaults(self): | ||||||
|         utils.initialize_widget( |         utils.initialize_widget( | ||||||
| @ -210,8 +241,8 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|                 ('tinted icon with modified white', 'tint+whitehack'), |                 ('tinted icon with modified white', 'tint+whitehack'), | ||||||
|                 ('tinted icon with 50% saturation', 'tint+saturation50') |                 ('tinted icon with 50% saturation', 'tint+saturation50') | ||||||
|             ], |             ], | ||||||
|             selected_value=self.vm.features.get('gui-default-trayicon-mode', |             selected_value=utils.get_feature( | ||||||
|                                                 None)) |                 self.vm, 'gui-default-trayicon-mode', None)) | ||||||
| 
 | 
 | ||||||
|         utils.initialize_widget( |         utils.initialize_widget( | ||||||
|             widget=self.securecopy, |             widget=self.securecopy, | ||||||
| @ -220,8 +251,8 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|                 ('Ctrl+Shift+C', 'Ctrl-Shift-c'), |                 ('Ctrl+Shift+C', 'Ctrl-Shift-c'), | ||||||
|                 ('Ctrl+Win+C', 'Ctrl-Mod4-c'), |                 ('Ctrl+Win+C', 'Ctrl-Mod4-c'), | ||||||
|             ], |             ], | ||||||
|             selected_value=self.vm.features.get( |             selected_value=utils.get_feature( | ||||||
|                 'gui-default-secure-copy-sequence', None)) |                 self.vm, 'gui-default-secure-copy-sequence', None)) | ||||||
| 
 | 
 | ||||||
|         utils.initialize_widget( |         utils.initialize_widget( | ||||||
|             widget=self.securepaste, |             widget=self.securepaste, | ||||||
| @ -231,15 +262,25 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|                 ('Ctrl+Win+V', 'Ctrl-Mod4-v'), |                 ('Ctrl+Win+V', 'Ctrl-Mod4-v'), | ||||||
|                 ('Ctrl+Insert', 'Ctrl-Ins'), |                 ('Ctrl+Insert', 'Ctrl-Ins'), | ||||||
|             ], |             ], | ||||||
|             selected_value=self.vm.features.get( |             selected_value=utils.get_feature( | ||||||
|                 'gui-default-secure-paste-sequence', None)) |                 self.vm, 'gui-default-secure-paste-sequence', None)) | ||||||
| 
 | 
 | ||||||
|     def __apply_feature_change(self, widget, feature): |     def __apply_feature_change(self, widget, feature): | ||||||
|         if utils.did_widget_selection_change(widget): |         if utils.did_widget_selection_change(widget): | ||||||
|             if widget.currentData() is None: |             if widget.currentData() is None: | ||||||
|                 del self.vm.features[feature] |                 try: | ||||||
|  |                     del self.vm.features[feature] | ||||||
|  |                 except exc.QubesDaemonCommunicationError: | ||||||
|  |                     self.errors.append( | ||||||
|  |                         "Failed to set {} due to insufficient " | ||||||
|  |                         "permissions".format(feature)) | ||||||
|             else: |             else: | ||||||
|                 self.vm.features[feature] = widget.currentData() |                 try: | ||||||
|  |                     self.vm.features[feature] = widget.currentData() | ||||||
|  |                 except exc.QubesDaemonCommunicationError as ex: | ||||||
|  |                     self.errors.append( | ||||||
|  |                         "Failed to set {} due to insufficient " | ||||||
|  |                         "permissions".format(feature)) | ||||||
| 
 | 
 | ||||||
|     def __apply_gui_defaults(self): |     def __apply_gui_defaults(self): | ||||||
|         self.__apply_feature_change(widget=self.allow_fullscreen, |         self.__apply_feature_change(widget=self.allow_fullscreen, | ||||||
| @ -255,25 +296,35 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
| 
 | 
 | ||||||
|     def __init_mem_defaults__(self): |     def __init_mem_defaults__(self): | ||||||
|         # qmemman settings |         # qmemman settings | ||||||
|         self.qmemman_config = ConfigParser() |         try: | ||||||
|         self.vm_min_mem_val = '200MiB'  # str(qmemman_algo.MIN_PREFMEM) |             self.qmemman_config = ConfigParser() | ||||||
|         self.dom0_mem_boost_val = '350MiB'  # str(qmemman_algo.DOM0_MEM_BOOST) |             self.vm_min_mem_val = '200MiB'  # str(qmemman_algo.MIN_PREFMEM) | ||||||
|  |             self.dom0_mem_boost_val = '350MiB'  # str(qmemman_algo.DOM0_MEM_BOOST) | ||||||
| 
 | 
 | ||||||
|         self.qmemman_config.read(qmemman_config_path) |             self.qmemman_config.read(qmemman_config_path) | ||||||
|         if self.qmemman_config.has_section('global'): |             if self.qmemman_config.has_section('global'): | ||||||
|             self.vm_min_mem_val = \ |                 self.vm_min_mem_val = \ | ||||||
|                 self.qmemman_config.get('global', 'vm-min-mem') |                     self.qmemman_config.get('global', 'vm-min-mem') | ||||||
|             self.dom0_mem_boost_val = \ |                 self.dom0_mem_boost_val = \ | ||||||
|                 self.qmemman_config.get('global', 'dom0-mem-boost') |                     self.qmemman_config.get('global', 'dom0-mem-boost') | ||||||
| 
 | 
 | ||||||
|         self.vm_min_mem_val = parse_size(self.vm_min_mem_val) |             self.vm_min_mem_val = parse_size(self.vm_min_mem_val) | ||||||
|         self.dom0_mem_boost_val = parse_size(self.dom0_mem_boost_val) |             self.dom0_mem_boost_val = parse_size(self.dom0_mem_boost_val) | ||||||
| 
 | 
 | ||||||
|         self.min_vm_mem.setValue(int(self.vm_min_mem_val / 1024 / 1024)) |             self.min_vm_mem.setValue( | ||||||
|         self.dom0_mem_boost.setValue(int(self.dom0_mem_boost_val / 1024 / 1024)) |                 int(self.vm_min_mem_val / 1024 / 1024)) | ||||||
|  |             self.dom0_mem_boost.setValue( | ||||||
|  |                 int(self.dom0_mem_boost_val / 1024 / 1024)) | ||||||
|  |         except exc.QubesException: | ||||||
|  |             self.min_vm_mem.setEnabled(False) | ||||||
|  |             self.dom0_mem_boost.setEnabled(False) | ||||||
| 
 | 
 | ||||||
|     def __apply_mem_defaults__(self): |     def __apply_mem_defaults__(self): | ||||||
| 
 | 
 | ||||||
|  |         if not self.min_vm_mem.isEnabled() or \ | ||||||
|  |                 not self.dom0_mem_boost.isEnabled(): | ||||||
|  |             return | ||||||
|  | 
 | ||||||
|         # qmemman settings |         # qmemman settings | ||||||
|         current_min_vm_mem = self.min_vm_mem.value() |         current_min_vm_mem = self.min_vm_mem.value() | ||||||
|         current_dom0_mem_boost = self.dom0_mem_boost.value() |         current_dom0_mem_boost = self.dom0_mem_boost.value() | ||||||
| @ -295,9 +346,14 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|                     'global', 'cache-margin-factor', str(1.3)) |                     'global', 'cache-margin-factor', str(1.3)) | ||||||
|                 # removed qmemman_algo.CACHE_FACTOR |                 # removed qmemman_algo.CACHE_FACTOR | ||||||
| 
 | 
 | ||||||
|                 qmemman_config_file = open(qmemman_config_path, 'a') |                 try: | ||||||
|                 self.qmemman_config.write(qmemman_config_file) |                     qmemman_config_file = open(qmemman_config_path, 'a') | ||||||
|                 qmemman_config_file.close() |                     self.qmemman_config.write(qmemman_config_file) | ||||||
|  |                     qmemman_config_file.close() | ||||||
|  |                 except Exception as ex: | ||||||
|  |                     self.errors.append( | ||||||
|  |                         "Failed to set memory settings due to {}".format( | ||||||
|  |                             str(ex))) | ||||||
| 
 | 
 | ||||||
|             else: |             else: | ||||||
|                 # If there already is a 'global' section, we don't use |                 # If there already is a 'global' section, we don't use | ||||||
| @ -312,7 +368,14 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
| 
 | 
 | ||||||
|                 config_lines = [] |                 config_lines = [] | ||||||
| 
 | 
 | ||||||
|                 qmemman_config_file = open(qmemman_config_path, 'r') |                 try: | ||||||
|  |                     qmemman_config_file = open(qmemman_config_path, 'r') | ||||||
|  |                 except Exception as ex: | ||||||
|  |                     self.errors.append( | ||||||
|  |                         "Failed to set memory settings due to {}".format( | ||||||
|  |                             str(ex))) | ||||||
|  |                     return | ||||||
|  | 
 | ||||||
|                 for line in qmemman_config_file: |                 for line in qmemman_config_file: | ||||||
|                     if line.strip().startswith('vm-min-mem'): |                     if line.strip().startswith('vm-min-mem'): | ||||||
|                         config_lines.append(lines_to_add['vm-min-mem']) |                         config_lines.append(lines_to_add['vm-min-mem']) | ||||||
| @ -328,28 +391,44 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|                 for line in lines_to_add: |                 for line in lines_to_add: | ||||||
|                     config_lines.append(line) |                     config_lines.append(line) | ||||||
| 
 | 
 | ||||||
|                 qmemman_config_file = open(qmemman_config_path, 'w') |                 try: | ||||||
|                 qmemman_config_file.writelines(config_lines) |                     qmemman_config_file = open(qmemman_config_path, 'w') | ||||||
|                 qmemman_config_file.close() |                     qmemman_config_file.writelines(config_lines) | ||||||
|  |                     qmemman_config_file.close() | ||||||
|  |                 except Exception as ex: | ||||||
|  |                     self.errors.append( | ||||||
|  |                         "Failed to set memory settings due to {}".format( | ||||||
|  |                             str(ex))) | ||||||
|  |                     return | ||||||
| 
 | 
 | ||||||
|     def __init_updates__(self): |     def __init_updates__(self): | ||||||
|         self.updates_dom0_val = bool( |         self.updates_dom0_val = bool( | ||||||
|             self.qubes_app.domains['dom0'].features.get( |             utils.get_feature(self.qubes_app.domains['dom0'], | ||||||
|                 'service.qubes-update-check', True)) |                               'service.qubes-update-check', | ||||||
|  |                               True)) | ||||||
| 
 | 
 | ||||||
|         self.updates_dom0.setChecked(self.updates_dom0_val) |         self.updates_dom0.setChecked(self.updates_dom0_val) | ||||||
| 
 | 
 | ||||||
|         self.updates_vm.setChecked(self.qubes_app.check_updates_vm) |         try: | ||||||
|  |             self.updates_vm.setChecked(self.qubes_app.check_updates_vm) | ||||||
|  |         except exc.QubesPropertyAccessError: | ||||||
|  |             self.updates_vm.isEnabled(False) | ||||||
|  | 
 | ||||||
|         self.enable_updates_all.clicked.connect(self.__enable_updates_all) |         self.enable_updates_all.clicked.connect(self.__enable_updates_all) | ||||||
|         self.disable_updates_all.clicked.connect(self.__disable_updates_all) |         self.disable_updates_all.clicked.connect(self.__disable_updates_all) | ||||||
| 
 | 
 | ||||||
|         self.repos = repos = dict() |         self.repos = repos = dict() | ||||||
|         for i in _run_qrexec_repo('qubes.repos.List').split('\n'): |         try: | ||||||
|             lst = i.split('\0') |             for i in _run_qrexec_repo('qubes.repos.List').split('\n'): | ||||||
|             # Keyed by repo name |                 lst = i.split('\0') | ||||||
|             dct = repos[lst[0]] = dict() |                 # Keyed by repo name | ||||||
|             dct['prettyname'] = lst[1] |                 dct = repos[lst[0]] = dict() | ||||||
|             dct['enabled'] = lst[2] == 'enabled' |                 dct['prettyname'] = lst[1] | ||||||
|  |                 dct['enabled'] = lst[2] == 'enabled' | ||||||
|  |         except Exception as ex: | ||||||
|  |             self.dom0_updates_repo.setEnabled(False) | ||||||
|  |             self.itl_tmpl_updates_repo.setEnabled(False) | ||||||
|  |             self.comm_tmpl_updates_repo.setEnabled(False) | ||||||
| 
 | 
 | ||||||
|         if repos['qubes-dom0-unstable']['enabled']: |         if repos['qubes-dom0-unstable']['enabled']: | ||||||
|             self.dom0_updates_repo.setCurrentIndex(3) |             self.dom0_updates_repo.setCurrentIndex(3) | ||||||
| @ -401,18 +480,38 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|         self.__set_updates_all(False) |         self.__set_updates_all(False) | ||||||
| 
 | 
 | ||||||
|     def __set_updates_all(self, state): |     def __set_updates_all(self, state): | ||||||
|  |         errors = [] | ||||||
|         for vm in self.qubes_app.domains: |         for vm in self.qubes_app.domains: | ||||||
|             if vm.klass != "AdminVM": |             if vm.klass != "AdminVM": | ||||||
|                 vm.features['service.qubes-update-check'] = state |                 try: | ||||||
|  |                     vm.features['service.qubes-update-check'] = state | ||||||
|  |                 except exc.QubesDaemonCommunicationError: | ||||||
|  |                     errors.append(vm.name) | ||||||
|  | 
 | ||||||
|  |         if errors: | ||||||
|  |             QtWidgets.QMessageBox.warning( | ||||||
|  |                 self, "Error!", | ||||||
|  |                 "Failed to set state for some qubes: {}".format( | ||||||
|  |                     ", ".join(errors))) | ||||||
| 
 | 
 | ||||||
|     def __apply_updates__(self): |     def __apply_updates__(self): | ||||||
|         if self.updates_dom0.isChecked() != self.updates_dom0_val: |         if self.updates_dom0.isEnabled() and \ | ||||||
|             self.qubes_app.domains['dom0'].features[ |                 self.updates_dom0.isChecked() != self.updates_dom0_val: | ||||||
|                 'service.qubes-update-check'] = \ |             try: | ||||||
|                 self.updates_dom0.isChecked() |                 self.qubes_app.domains['dom0'].features[ | ||||||
|  |                     'service.qubes-update-check'] = \ | ||||||
|  |                     self.updates_dom0.isChecked() | ||||||
|  |             except exc.QubesDaemonCommunicationError: | ||||||
|  |                 self.errors.append("Failed to change dom0 update value due " | ||||||
|  |                                    "to insufficient permissions.") | ||||||
| 
 | 
 | ||||||
|         if self.qubes_app.check_updates_vm != self.updates_vm.isChecked(): |         if self.updates_vm.isEnabled() and \ | ||||||
|             self.qubes_app.check_updates_vm = self.updates_vm.isChecked() |                 self.qubes_app.check_updates_vm != self.updates_vm.isChecked(): | ||||||
|  |             try: | ||||||
|  |                 self.qubes_app.check_updates_vm = self.updates_vm.isChecked() | ||||||
|  |             except exc.QubesPropertyAccessError: | ||||||
|  |                 self.errors.append("Failed to set qube update checking due " | ||||||
|  |                                    "to insufficient permissions.") | ||||||
| 
 | 
 | ||||||
|     def _manage_repos(self, repolist, action): |     def _manage_repos(self, repolist, action): | ||||||
|         for name in repolist: |         for name in repolist: | ||||||
| @ -470,17 +569,21 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|         self._manage_repos(disable, 'Disable') |         self._manage_repos(disable, 'Disable') | ||||||
| 
 | 
 | ||||||
|     def __apply_repos__(self): |     def __apply_repos__(self): | ||||||
|         self._handle_dom0_updates_combobox( |         if self.dom0_updates_repo.isEnabled(): | ||||||
|             self.dom0_updates_repo.currentIndex()) |             self._handle_dom0_updates_combobox( | ||||||
|         self._handle_itl_tmpl_updates_combobox( |                 self.dom0_updates_repo.currentIndex()) | ||||||
|             self.itl_tmpl_updates_repo.currentIndex()) |         if self.itl_tmpl_updates_repo.isEnabled(): | ||||||
|         self._handle_comm_tmpl_updates_combobox( |             self._handle_itl_tmpl_updates_combobox( | ||||||
|             self.comm_tmpl_updates_repo.currentIndex()) |                 self.itl_tmpl_updates_repo.currentIndex()) | ||||||
|  |         if self.comm_tmpl_updates_repo.isEnabled(): | ||||||
|  |             self._handle_comm_tmpl_updates_combobox( | ||||||
|  |                 self.comm_tmpl_updates_repo.currentIndex()) | ||||||
| 
 | 
 | ||||||
|     def reject(self): |     def reject(self): | ||||||
|         self.done(0) |         self.done(0) | ||||||
| 
 | 
 | ||||||
|     def save_and_apply(self): |     def save_and_apply(self): | ||||||
|  |         self.errors = [] | ||||||
| 
 | 
 | ||||||
|         self.__apply_system_defaults__() |         self.__apply_system_defaults__() | ||||||
|         self.__apply_kernel_defaults__() |         self.__apply_kernel_defaults__() | ||||||
| @ -489,6 +592,11 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings, | |||||||
|         self.__apply_repos__() |         self.__apply_repos__() | ||||||
|         self.__apply_gui_defaults() |         self.__apply_gui_defaults() | ||||||
| 
 | 
 | ||||||
|  |         if self.errors: | ||||||
|  |             err_msg = "Failed to apply some settings:\n" + "\n".join( | ||||||
|  |                 self.errors) | ||||||
|  |             QtWidgets.QMessageBox.warning(self, "Error", err_msg) | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| def main(): | def main(): | ||||||
|     utils.run_synchronous(GlobalSettingsWindow) |     utils.run_synchronous(GlobalSettingsWindow) | ||||||
|  | |||||||
| @ -105,8 +105,11 @@ class GlobalSettingsTest(unittest.TestCase): | |||||||
| 
 | 
 | ||||||
|         # correct defaultDispVM |         # correct defaultDispVM | ||||||
|         selected_default_dispvm = self.dialog.default_dispvm_combo.currentText() |         selected_default_dispvm = self.dialog.default_dispvm_combo.currentText() | ||||||
|         correct_default_dispvm = \ |         current_default_dispvm = getattr(self.qapp, 'default_dispvm', None) | ||||||
|             str(getattr(self.qapp, 'default_dispvm', "(none)")) |         if current_default_dispvm is None: | ||||||
|  |             correct_default_dispvm = "(none)" | ||||||
|  |         else: | ||||||
|  |             correct_default_dispvm = str(current_default_dispvm) | ||||||
|         self.assertTrue( |         self.assertTrue( | ||||||
|             selected_default_dispvm.startswith(correct_default_dispvm), |             selected_default_dispvm.startswith(correct_default_dispvm), | ||||||
|             "Incorrect defaultDispVM loaded") |             "Incorrect defaultDispVM loaded") | ||||||
| @ -118,11 +121,8 @@ class GlobalSettingsTest(unittest.TestCase): | |||||||
| 
 | 
 | ||||||
|     def test_02_dom0_updates_load(self): |     def test_02_dom0_updates_load(self): | ||||||
|         # check dom0 updates |         # check dom0 updates | ||||||
|         try: |         dom0_updates = self.qapp.domains[ | ||||||
|             dom0_updates = self.qapp.domains[ |             'dom0'].features.get('service.qubes-update-check', True) | ||||||
|                 'dom0'].features['service.qubes-update-check'] |  | ||||||
|         except KeyError: |  | ||||||
|             dom0_updates = True |  | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(bool(dom0_updates), |         self.assertEqual(bool(dom0_updates), | ||||||
|                          self.dialog.updates_dom0.isChecked(), |                          self.dialog.updates_dom0.isChecked(), | ||||||
|  | |||||||
| @ -31,6 +31,7 @@ from contextlib import suppress | |||||||
| import sys | import sys | ||||||
| import qasync | import qasync | ||||||
| from qubesadmin import events | from qubesadmin import events | ||||||
|  | from qubesadmin import exc | ||||||
| 
 | 
 | ||||||
| from PyQt5 import QtWidgets, QtCore, QtGui  # pylint: disable=import-error | from PyQt5 import QtWidgets, QtCore, QtGui  # pylint: disable=import-error | ||||||
| 
 | 
 | ||||||
| @ -91,11 +92,18 @@ class SizeSpinBox(QtWidgets.QSpinBox): | |||||||
|         return int(float(value) * multiplier) |         return int(float(value) * multiplier) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | def get_feature(vm, feature_name, default_value): | ||||||
|  |     try: | ||||||
|  |         return vm.features.get(feature_name, default_value) | ||||||
|  |     except exc.QubesDaemonCommunicationError: | ||||||
|  |         return default_value | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def get_boolean_feature(vm, feature_name): | def get_boolean_feature(vm, feature_name): | ||||||
|     """heper function to get a feature converted to a Bool if it does exist. |     """heper function to get a feature converted to a Bool if it does exist. | ||||||
|     Necessary because of the true/false in features being coded as 1/empty |     Necessary because of the true/false in features being coded as 1/empty | ||||||
|     string.""" |     string.""" | ||||||
|     result = vm.features.get(feature_name, None) |     result = get_feature(vm, feature_name, None) | ||||||
|     if result is not None: |     if result is not None: | ||||||
|         result = bool(result) |         result = bool(result) | ||||||
|     return result |     return result | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marta Marczykowska-Górecka
						Marta Marczykowska-Górecka