Use the new QubesDaemonAccessError

Replaces the old, unified approach.
This commit is contained in:
Marta Marczykowska-Górecka 2020-08-11 01:08:48 +02:00
parent 8eb61b11ae
commit ee5625b65c
No known key found for this signature in database
GPG Key ID: 9A752C30B26FD04B
11 changed files with 168 additions and 115 deletions

View File

@ -36,7 +36,6 @@ import pwd
import os import os
import shutil import shutil
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class BackupThread(QtCore.QThread): class BackupThread(QtCore.QThread):
def __init__(self, vm): def __init__(self, vm):
@ -50,7 +49,9 @@ class BackupThread(QtCore.QThread):
if not self.vm.is_running(): if not self.vm.is_running():
self.vm.start() self.vm.start()
except exc.QubesException: except exc.QubesException:
# we may have insufficient exceptions to ensure the qube is running # we may have insufficient permissions to ensure the qube is running
# let us hope for the best (worst case scenario, we will fail at the
# next step
pass pass
try: try:
@ -94,6 +95,8 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
self.select_dir_page.isComplete = self.has_selected_dir_and_pass self.select_dir_page.isComplete = self.has_selected_dir_and_pass
# FIXME # FIXME
# this causes to run isComplete() twice, I don't know why # this causes to run isComplete() twice, I don't know why
# update 2020-08: selectedChanged is emitted once,
# but completeChanged twice. Somehow.
self.select_vms_widget.selectedChanged.connect( self.select_vms_widget.selectedChanged.connect(
self.select_vms_page.completeChanged.emit) self.select_vms_page.completeChanged.emit)
self.passphrase_line_edit.textChanged.connect( self.passphrase_line_edit.textChanged.connect(
@ -144,7 +147,7 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
result = [] result = []
for domain in self.qubes_app.domains: for domain in self.qubes_app.domains:
if getattr(domain, 'include_in_backups', None): if getattr(domain, 'include_in_backups', False):
result.append(domain.name) result.append(domain.name)
return result return result
@ -209,14 +212,23 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self, vm): def __init__(self, vm):
self.vm = vm self.vm = vm
if vm.qid == 0: if vm.klass == 'AdminVM':
local_user = grp.getgrnam('qubes').gr_mem[0] local_user = grp.getgrnam('qubes').gr_mem[0]
home_dir = pwd.getpwnam(local_user).pw_dir home_dir = pwd.getpwnam(local_user).pw_dir
self.size = shutil.disk_usage(home_dir)[1] self.size = shutil.disk_usage(home_dir)[1]
else: else:
try:
self.size = vm.get_disk_utilization() self.size = vm.get_disk_utilization()
super(BackupVMsWindow.VmListItem, self).__init__( except exc.QubesDaemonAccessError:
vm.name + " (" + admin_utils.size_to_human(self.size) + ")") self.size = None
if self.size is not None:
text = vm.name + " (" + admin_utils.size_to_human(
self.size) + ")"
else:
text = vm.name + " (size unavailable)"
self.size = 0
super(BackupVMsWindow.VmListItem, self).__init__(text)
def __fill_vms_list__(self, selected=None): def __fill_vms_list__(self, selected=None):
for vm in self.qubes_app.domains: for vm in self.qubes_app.domains:
@ -307,7 +319,7 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
backup_summary = self.qubes_app.qubesd_call( backup_summary = self.qubes_app.qubesd_call(
'dom0', 'admin.backup.Info', 'dom0', 'admin.backup.Info',
backup_utils.get_profile_name(True)).decode() backup_utils.get_profile_name(True)).decode()
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
backup_summary = "Failed to get backup summary: " \ backup_summary = "Failed to get backup summary: " \
"insufficient permissions" "insufficient permissions"

View File

@ -46,7 +46,7 @@ def fill_appvms_list(dialog):
if utils.get_feature(vm, 'internal', False) or vm.klass == 'TemplateVM': if utils.get_feature(vm, 'internal', False) or vm.klass == 'TemplateVM':
continue continue
if utils.is_running(vm, False) and vm.qid != 0: if utils.is_running(vm, False) and vm.klass != 'AdminVM':
dialog.appvm_combobox.addItem(vm.name) dialog.appvm_combobox.addItem(vm.name)

View File

@ -83,7 +83,7 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog,
self.tr("Warning!"), self.tr("Warning!"),
self.tr("Qube must be turned off before booting it from " self.tr("Qube must be turned off before booting it from "
"device. Please turn off the qube.")) "device. Please turn off the qube."))
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
QtWidgets.QMessageBox.warning( QtWidgets.QMessageBox.warning(
self, self,
self.tr("Warning!"), self.tr("Warning!"),
@ -111,7 +111,7 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog,
try: try:
for device in domain.devices["block"]: for device in domain.devices["block"]:
device_choice.append((str(device), device)) device_choice.append((str(device), device))
except exc.QubesException: except exc.QubesDaemonAccessError:
# insufficient permissions # insufficient permissions
pass pass

View File

@ -60,12 +60,16 @@ class CloneVMDlg(QtWidgets.QDialog, Ui_CloneVMDlg):
self.update_label() self.update_label()
try:
utils.initialize_widget_with_default( utils.initialize_widget_with_default(
widget=self.storage_pool, widget=self.storage_pool,
choices=[(str(pool), pool) for pool in self.app.pools.values()], choices=[(str(pool), pool) for pool in self.app.pools.values()],
add_qubes_default=True, add_qubes_default=True,
mark_existing_as_default=True, mark_existing_as_default=True,
default_value=self.app.default_pool) default_value=self.app.default_pool)
except qubesadmin.exc.QubesDaemonAccessError:
self.storage_pool.clear()
self.storage_pool.addItem("(default)", qubesadmin.DEFAULT)
self.set_clone_name() self.set_clone_name()

View File

@ -123,7 +123,7 @@ class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
add_qubes_default=True, add_qubes_default=True,
mark_existing_as_default=True, mark_existing_as_default=True,
default_value=self.app.default_pool) default_value=self.app.default_pool)
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.storage_pool.clear() self.storage_pool.clear()
self.storage_pool.addItem("(default)", qubesadmin.DEFAULT) self.storage_pool.addItem("(default)", qubesadmin.DEFAULT)

View File

@ -90,41 +90,51 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
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"))
def setup_widget_with_vms(self, widget, filter_function,
allow_none, holder, property_name):
try:
utils.initialize_widget_with_vms(
widget=widget,
qubes_app=self.qubes_app,
filter_function=filter_function,
allow_none=allow_none,
holder=holder,
property_name=property_name
)
except exc.QubesDaemonAccessError:
widget.clear()
widget.setCurrentText("unavailable")
widget.setEnabled(False)
def __init_system_defaults__(self): def __init_system_defaults__(self):
# set up updatevm choice # set up updatevm choice
utils.initialize_widget_with_vms( self.setup_widget_with_vms(
widget=self.update_vm_combo, widget=self.update_vm_combo,
qubes_app=self.qubes_app,
filter_function=(lambda vm: vm.klass != 'TemplateVM'), filter_function=(lambda vm: vm.klass != 'TemplateVM'),
allow_none=True, allow_none=True,
holder=self.qubes_app, holder=self.qubes_app,
property_name="updatevm" property_name="updatevm")
)
# set up clockvm choice # set up clockvm choice
utils.initialize_widget_with_vms( self.setup_widget_with_vms(
widget=self.clock_vm_combo, widget=self.clock_vm_combo,
qubes_app=self.qubes_app,
filter_function=(lambda vm: vm.klass != 'TemplateVM'), filter_function=(lambda vm: vm.klass != 'TemplateVM'),
allow_none=True, allow_none=True,
holder=self.qubes_app, holder=self.qubes_app,
property_name="clockvm" property_name="clockvm")
)
# set up default netvm # set up default netvm
utils.initialize_widget_with_vms( self.setup_widget_with_vms(
widget=self.default_netvm_combo, widget=self.default_netvm_combo,
qubes_app=self.qubes_app, filter_function=(lambda vm: getattr(
filter_function=(lambda vm: getattr(vm, 'provides_network', False)), 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")
)
# default template # default template
utils.initialize_widget_with_vms( self.setup_widget_with_vms(
widget=self.default_template_combo, widget=self.default_template_combo,
qubes_app=self.qubes_app,
filter_function=(lambda vm: vm.klass == 'TemplateVM'), filter_function=(lambda vm: vm.klass == 'TemplateVM'),
allow_none=True, allow_none=True,
holder=self.qubes_app, holder=self.qubes_app,
@ -132,9 +142,8 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
) )
# default dispvm # default dispvm
utils.initialize_widget_with_vms( self.setup_widget_with_vms(
widget=self.default_dispvm_combo, widget=self.default_dispvm_combo,
qubes_app=self.qubes_app,
filter_function=(lambda vm: getattr( filter_function=(lambda vm: getattr(
vm, 'template_for_dispvms', False)), vm, 'template_for_dispvms', False)),
allow_none=True, allow_none=True,
@ -194,8 +203,9 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
allow_none=True, allow_none=True,
holder=self.qubes_app, holder=self.qubes_app,
property_name='default_kernel') property_name='default_kernel')
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.default_kernel_combo.clear() self.default_kernel_combo.clear()
self.default_kernel_combo.setCurrentText("unavailable")
self.default_kernel_combo.setEnabled(False) self.default_kernel_combo.setEnabled(False)
def __apply_kernel_defaults__(self): def __apply_kernel_defaults__(self):
@ -270,14 +280,14 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
if widget.currentData() is None: if widget.currentData() is None:
try: try:
del self.vm.features[feature] del self.vm.features[feature]
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
self.errors.append( self.errors.append(
"Failed to set {} due to insufficient " "Failed to set {} due to insufficient "
"permissions".format(feature)) "permissions".format(feature))
else: else:
try: try:
self.vm.features[feature] = widget.currentData() self.vm.features[feature] = widget.currentData()
except exc.QubesDaemonCommunicationError as ex: except exc.QubesDaemonAccessError as ex:
self.errors.append( self.errors.append(
"Failed to set {} due to insufficient " "Failed to set {} due to insufficient "
"permissions".format(feature)) "permissions".format(feature))
@ -411,7 +421,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
try: try:
self.updates_vm.setChecked(self.qubes_app.check_updates_vm) self.updates_vm.setChecked(self.qubes_app.check_updates_vm)
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.updates_vm.isEnabled(False) 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)
@ -485,7 +495,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
if vm.klass != "AdminVM": if vm.klass != "AdminVM":
try: try:
vm.features['service.qubes-update-check'] = state vm.features['service.qubes-update-check'] = state
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
errors.append(vm.name) errors.append(vm.name)
if errors: if errors:
@ -501,7 +511,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.qubes_app.domains['dom0'].features[ self.qubes_app.domains['dom0'].features[
'service.qubes-update-check'] = \ 'service.qubes-update-check'] = \
self.updates_dom0.isChecked() self.updates_dom0.isChecked()
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
self.errors.append("Failed to change dom0 update value due " self.errors.append("Failed to change dom0 update value due "
"to insufficient permissions.") "to insufficient permissions.")
@ -509,7 +519,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.qubes_app.check_updates_vm != self.updates_vm.isChecked(): self.qubes_app.check_updates_vm != self.updates_vm.isChecked():
try: try:
self.qubes_app.check_updates_vm = self.updates_vm.isChecked() self.qubes_app.check_updates_vm = self.updates_vm.isChecked()
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.errors.append("Failed to set qube update checking due " self.errors.append("Failed to set qube update checking due "
"to insufficient permissions.") "to insufficient permissions.")

View File

@ -209,25 +209,29 @@ class VmInfo():
def update_power_state(self): def update_power_state(self):
try: try:
self.state['power'] = self.vm.get_power_state() self.state['power'] = self.vm.get_power_state()
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.state['power'] = "" self.state['power'] = ""
self.state['outdated'] = "" self.state['outdated'] = ""
try: try:
if self.vm.is_running(): if manager_utils.is_running(self.vm, False):
if hasattr(self.vm, 'template') and \ if hasattr(self.vm, 'template') and \
self.vm.template.is_running(): manager_utils.is_running(self.vm.template, False):
self.state['outdated'] = "to-be-outdated" self.state['outdated'] = "to-be-outdated"
else: else:
try:
for vol in self.vm.volumes.values(): for vol in self.vm.volumes.values():
if vol.is_outdated(): if vol.is_outdated():
self.state['outdated'] = "outdated" self.state['outdated'] = "outdated"
break break
except exc.QubesDaemonAccessError:
pass
if self.vm.klass in {'TemplateVM', 'StandaloneVM'} and \ if self.vm.klass in {'TemplateVM', 'StandaloneVM'} and \
self.vm.features.get('updates-available', False): manager_utils.get_feature(
self.vm, 'updates-available', False):
self.state['outdated'] = 'update' self.state['outdated'] = 'update'
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
pass pass
def update(self, update_size_on_disk=False, event=None): def update(self, update_size_on_disk=False, event=None):
@ -259,14 +263,12 @@ class VmInfo():
if hasattr(self.vm, 'netvm') \ if hasattr(self.vm, 'netvm') \
and self.vm.property_is_default("netvm"): and self.vm.property_is_default("netvm"):
self.netvm = "default (" + self.netvm + ")" self.netvm = "default (" + self.netvm + ")"
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
pass pass
if not event or event.endswith(':internal'): if not event or event.endswith(':internal'):
try: self.internal = manager_utils.get_boolean_feature(
self.internal = self.vm.features.get('internal', False) self.vm, 'internal')
except exc.QubesPropertyAccessError:
self.internal = False
if not event or event.endswith(':ip'): if not event or event.endswith(':ip'):
self.ip = getattr(self.vm, 'ip', "n/a") self.ip = getattr(self.vm, 'ip', "n/a")
@ -286,8 +288,9 @@ class VmInfo():
self.dvm = "default (" + str(self.dvm) + ")" self.dvm = "default (" + str(self.dvm) + ")"
elif self.dvm is not None: elif self.dvm is not None:
self.dvm = str(self.dvm) self.dvm = str(self.dvm)
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.dvm = None if self.dvm is not None:
self.dvm = str(self.dvm)
if not event or event.endswith(':template_for_dispvms'): if not event or event.endswith(':template_for_dispvms'):
self.dvm_template = getattr(self.vm, 'template_for_dispvms', None) self.dvm_template = getattr(self.vm, 'template_for_dispvms', None)
@ -296,7 +299,7 @@ class VmInfo():
try: try:
self.disk_float = float(self.vm.get_disk_utilization()) self.disk_float = float(self.vm.get_disk_utilization())
self.disk = str(round(self.disk_float/(1024*1024), 2)) + " MiB" self.disk = str(round(self.disk_float/(1024*1024), 2)) + " MiB"
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
self.disk_float = None self.disk_float = None
self.disk = None self.disk = None
@ -422,7 +425,7 @@ class QubesTableModel(QAbstractTableModel):
pixmap.load(icon_name) pixmap.load(icon_name)
self.klass_pixmap[vm.klass] = pixmap.scaled(icon_size) self.klass_pixmap[vm.klass] = pixmap.scaled(icon_size)
return self.klass_pixmap[vm.klass] return self.klass_pixmap[vm.klass]
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return None return None
if col_name == "Label": if col_name == "Label":
@ -432,7 +435,7 @@ class QubesTableModel(QAbstractTableModel):
icon = QIcon.fromTheme(vm.label.icon) icon = QIcon.fromTheme(vm.label.icon)
self.label_pixmap[vm.label] = icon.pixmap(icon_size) self.label_pixmap[vm.label] = icon.pixmap(icon_size)
return self.label_pixmap[vm.label] return self.label_pixmap[vm.label]
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return None return None
if role == Qt.FontRole: if role == Qt.FontRole:
@ -507,7 +510,7 @@ class VmShutdownMonitor(QObject):
def check_if_vm_has_shutdown(self): def check_if_vm_has_shutdown(self):
vm = self.vm vm = self.vm
vm_is_running = vm.is_running() vm_is_running = manager_utils.is_running(vm, False)
try: try:
vm_start_time = datetime.fromtimestamp(float(vm.start_time)) vm_start_time = datetime.fromtimestamp(float(vm.start_time))
except (AttributeError, TypeError, ValueError): except (AttributeError, TypeError, ValueError):
@ -576,8 +579,12 @@ class UpdateVMThread(common_threads.QubesThread):
subprocess.check_call( subprocess.check_call(
["/usr/bin/qubes-dom0-update", "--clean", "--gui"]) ["/usr/bin/qubes-dom0-update", "--clean", "--gui"])
else: else:
if not self.vm.is_running(): if not manager_utils.is_running(self.vm, False):
try:
self.vm.start() self.vm.start()
except exc.QubesDaemonAccessError:
# permission denied, let us hope for the best
pass
# apply DSA-4371 # apply DSA-4371
with open('/usr/libexec/qubes-manager/dsa-4371-update', 'rb') \ with open('/usr/libexec/qubes-manager/dsa-4371-update', 'rb') \
as dsa4371update: as dsa4371update:
@ -848,9 +855,10 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
try: try:
if info.vm.klass in {'TemplateVM', 'StandaloneVM'} and \ if info.vm.klass in {'TemplateVM', 'StandaloneVM'} and \
info.vm.features.get('updates-available', False): manager_utils.get_feature(
info.vm, 'updates-available', False):
info.state['outdated'] = 'update' info.state['outdated'] = 'update'
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return return
def on_domain_added(self, _submitter, _event, vm, **_kwargs): def on_domain_added(self, _submitter, _event, vm, **_kwargs):
@ -874,7 +882,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
update(event="outdated") update(event="outdated")
self.proxy.invalidate() self.proxy.invalidate()
self.table_selection_changed() self.table_selection_changed()
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return # the VM was deleted before its status could be updated return # the VM was deleted before its status could be updated
except KeyError: # adding the VM failed for some reason except KeyError: # adding the VM failed for some reason
self.on_domain_added(None, None, vm) self.on_domain_added(None, None, vm)
@ -895,7 +903,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
try: try:
self.qubes_cache.get_vm(qid=vm.qid).update(event=event) self.qubes_cache.get_vm(qid=vm.qid).update(event=event)
self.proxy.invalidate() self.proxy.invalidate()
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return # the VM was deleted before its status could be updated return # the VM was deleted before its status could be updated
def load_manager_settings(self): def load_manager_settings(self):
@ -1092,8 +1100,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
def action_resumevm_triggered(self): def action_resumevm_triggered(self):
for vm_info in self.get_selected_vms(): for vm_info in self.get_selected_vms():
vm = vm_info.vm vm = vm_info.vm
if vm.get_power_state() in ["Paused", "Suspended"]:
try: try:
if vm.get_power_state() in ["Paused", "Suspended"]:
vm.unpause() vm.unpause()
except exc.QubesException as ex: except exc.QubesException as ex:
QMessageBox.warning( QMessageBox.warning(
@ -1104,7 +1112,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.start_vm(vm) self.start_vm(vm)
def start_vm(self, vm): def start_vm(self, vm):
if vm.is_running(): if manager_utils.is_running(vm, False):
return return
thread = StartVMThread(vm) thread = StartVMThread(vm)
@ -1179,17 +1187,29 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
if reply == QMessageBox.Yes: if reply == QMessageBox.Yes:
# in case the user shut down the VM in the meantime # in case the user shut down the VM in the meantime
if vm.is_running(): try:
if manager_utils.is_running(vm, False):
self.shutdown_vm(vm, and_restart=True) self.shutdown_vm(vm, and_restart=True)
else: else:
self.start_vm(vm) self.start_vm(vm)
except exc.QubesException as ex:
QMessageBox.warning(
self,
self.tr("Error restarting Qube!"),
self.tr("ERROR: {0}").format(ex))
# noinspection PyArgumentList # noinspection PyArgumentList
@pyqtSlot(name='on_action_killvm_triggered') @pyqtSlot(name='on_action_killvm_triggered')
def action_killvm_triggered(self): def action_killvm_triggered(self):
for vm_info in self.get_selected_vms(): for vm_info in self.get_selected_vms():
vm = vm_info.vm vm = vm_info.vm
if not (vm.is_running() or vm.is_paused()):
try:
vm_not_running = not (vm.is_running() or vm.is_paused())
except exc.QubesDaemonAccessError:
vm_not_running = False
if vm_not_running:
info = self.tr("Qube <b>'{0}'</b> is not running. Are you " info = self.tr("Qube <b>'{0}'</b> is not running. Are you "
"absolutely sure you want to try to kill it?<br>" "absolutely sure you want to try to kill it?<br>"
"<small>This will end <b>(not shutdown!)</b> " "<small>This will end <b>(not shutdown!)</b> "
@ -1213,8 +1233,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
QMessageBox.critical( QMessageBox.critical(
self, self.tr("Error while killing Qube!"), self, self.tr("Error while killing Qube!"),
self.tr( self.tr(
"<b>An exception ocurred while killing {0}.</b><br>" "<b>An exception occurred while killing {0}.</b>"
"ERROR: {1}").format(vm.name, ex)) "<br>ERROR: {1}").format(vm.name, ex))
return return
def open_settings(self, vm, tab='basic'): def open_settings(self, vm, tab='basic'):
@ -1252,7 +1272,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
def action_updatevm_triggered(self): def action_updatevm_triggered(self):
for vm_info in self.get_selected_vms(): for vm_info in self.get_selected_vms():
vm = vm_info.vm vm = vm_info.vm
if not vm.is_running(): if not manager_utils.is_running(vm, True):
reply = QMessageBox.question( reply = QMessageBox.question(
self, self.tr("Qube Update Confirmation"), self, self.tr("Qube Update Confirmation"),
self.tr( self.tr(
@ -1417,7 +1437,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
menu_empty = False menu_empty = False
self.logs_menu.setEnabled(not menu_empty) self.logs_menu.setEnabled(not menu_empty)
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
pass pass
@pyqtSlot('const QPoint&') @pyqtSlot('const QPoint&')

View File

@ -337,7 +337,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
no_firewall_state = \ no_firewall_state = \
netvm is not None and \ netvm is not None and \
not netvm.features.check_with_template('qubes-firewall', False) not netvm.features.check_with_template('qubes-firewall', False)
except qubesadmin.exc.QubesDaemonCommunicationError: except qubesadmin.exc.QubesDaemonAccessError:
no_firewall_state = False no_firewall_state = False
self.netvm_no_firewall_label.setVisible(no_firewall_state) self.netvm_no_firewall_label.setVisible(no_firewall_state)
@ -372,7 +372,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
self.delete_vm_button.setText( 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.qid == 0: if self.vm.klass == 'AdminVM':
self.vmlabel.setVisible(False) self.vmlabel.setVisible(False)
else: else:
try: try:
@ -382,7 +382,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
holder=self.vm) holder=self.vm)
self.vmlabel.setVisible(True) self.vmlabel.setVisible(True)
self.vmlabel.setEnabled(not utils.is_running(self.vm, False)) self.vmlabel.setEnabled(not utils.is_running(self.vm, False))
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.vmlabel.setEnabled(False) self.vmlabel.setEnabled(False)
if self.vm.klass == 'AppVM': if self.vm.klass == 'AppVM':
@ -393,7 +393,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
filter_function=(lambda vm: vm.klass == 'TemplateVM'), filter_function=(lambda vm: vm.klass == 'TemplateVM'),
holder=self.vm, holder=self.vm,
property_name='template') property_name='template')
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.template_name.setCurrentIndex(-1) self.template_name.setCurrentIndex(-1)
self.template_name.setEnabled(False) self.template_name.setEnabled(False)
@ -402,11 +402,11 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
utils.initialize_widget_with_vms( utils.initialize_widget_with_vms(
widget=self.template_name, widget=self.template_name,
qubes_app=self.qubesapp, qubes_app=self.qubesapp,
filter_function=(lambda vm: filter_function=(
getattr(vm, 'template_for_dispvms', False)), lambda vm: getattr(vm, 'template_for_dispvms', False)),
holder=self.vm, holder=self.vm,
property_name='template') property_name='template')
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.template_name.setCurrentIndex(-1) self.template_name.setCurrentIndex(-1)
self.template_name.setEnabled(False) self.template_name.setEnabled(False)
@ -426,7 +426,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
property_name='netvm', property_name='netvm',
allow_default=True, allow_default=True,
allow_none=True) allow_none=True)
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.netVM.setEnabled(False) self.netVM.setEnabled(False)
self.netVM.setCurrentIndex(-1) self.netVM.setCurrentIndex(-1)
@ -434,13 +434,13 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
try: try:
self.include_in_backups.setChecked(self.vm.include_in_backups) self.include_in_backups.setChecked(self.vm.include_in_backups)
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.include_in_backups.setEnabled(False) self.include_in_backups.setEnabled(False)
try: try:
self.autostart_vm.setChecked(self.vm.autostart) self.autostart_vm.setChecked(self.vm.autostart)
self.autostart_vm.setVisible(True) self.autostart_vm.setVisible(True)
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.autostart_vm.setEnabled(False) self.autostart_vm.setEnabled(False)
except AttributeError: except AttributeError:
self.autostart_vm.setVisible(False) self.autostart_vm.setVisible(False)
@ -602,7 +602,10 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
own_netvm = self.netVM.currentData() own_netvm = self.netVM.currentData()
if dispvm == qubesadmin.DEFAULT: 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
if dispvm == self.vm: if dispvm == self.vm:
self.warn_netvm_dispvm.setVisible(False) self.warn_netvm_dispvm.setVisible(False)
@ -613,7 +616,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
if own_netvm == qubesadmin.DEFAULT: if own_netvm == qubesadmin.DEFAULT:
try: try:
own_netvm = self.vm.property_get_default('netvm') own_netvm = self.vm.property_get_default('netvm')
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
# no point in warning if we don't know what we're warning about # no point in warning if we don't know what we're warning about
self.warn_netvm_dispvm.setVisible(False) self.warn_netvm_dispvm.setVisible(False)
return return
@ -731,7 +734,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
else: else:
try: try:
maxmem = self.vm.property_get_default('maxmem') maxmem = self.vm.property_get_default('maxmem')
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
maxmem = 0 maxmem = 0
if maxmem == 0: if maxmem == 0:
maxmem = vm_memory maxmem = vm_memory
@ -760,7 +763,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
property_name='kernel') property_name='kernel')
self.kernel.currentIndexChanged.connect(self.kernel_changed) self.kernel.currentIndexChanged.connect(self.kernel_changed)
self.kernel_opts.setText(getattr(self.vm, 'kernelopts', '-')) self.kernel_opts.setText(getattr(self.vm, 'kernelopts', '-'))
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.kernel_groupbox.setVisible(False) self.kernel_groupbox.setVisible(False)
else: else:
self.kernel_groupbox.setVisible(False) self.kernel_groupbox.setVisible(False)
@ -783,7 +786,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
) )
self.default_dispvm.currentIndexChanged.connect( self.default_dispvm.currentIndexChanged.connect(
self.check_warn_dispvmnetvm) self.check_warn_dispvmnetvm)
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.other_groupbox.setVisible(False) self.other_groupbox.setVisible(False)
self.check_warn_dispvmnetvm() self.check_warn_dispvmnetvm()
@ -1030,7 +1033,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
choices=choices, choices=choices,
holder=self.vm, holder=self.vm,
property_name='virt_mode') property_name='virt_mode')
except qubesadmin.exc.QubesPropertyAccessError: except qubesadmin.exc.QubesDaemonAccessError:
self.virt_mode.setEnabled(False) self.virt_mode.setEnabled(False)
if self.virt_mode.isEnabled() and old_mode is not None: if self.virt_mode.isEnabled() and old_mode is not None:
@ -1255,7 +1258,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
else ui_settingsdlg.QtCore.Qt.Unchecked) else ui_settingsdlg.QtCore.Qt.Unchecked)
self.services_list.addItem(item) self.services_list.addItem(item)
self.new_srv_dict[service] = self.vm.features[feature] self.new_srv_dict[service] = self.vm.features[feature]
except qubesadmin.exc.QubesDaemonCommunicationError: except qubesadmin.exc.QubesDaemonAccessError:
self.tabWidget.setTabEnabled(self.tabs_indices["services"], False) self.tabWidget.setTabEnabled(self.tabs_indices["services"], False)
return return
@ -1272,7 +1275,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
for feature in self.vm.template.features: for feature in self.vm.template.features:
if feature.startswith(service_prefix): if feature.startswith(service_prefix):
supported_services.add(feature[len(service_prefix):]) supported_services.add(feature[len(service_prefix):])
except qubesadmin.exc.QubesDaemonCommunicationError: except qubesadmin.exc.QubesDaemonAccessError:
pass pass
for service in sorted(supported_services): for service in sorted(supported_services):

View File

@ -345,7 +345,7 @@ class VMRow:
table_widget.setItem(row_no, columns.index('New template'), table_widget.setItem(row_no, columns.index('New template'),
self.dummy_new_item) self.dummy_new_item)
self.vm_state_change(is_vm_running(self.vm), row_no) self.vm_state_change(utils.is_running(self.vm, False), row_no)
def vm_state_change(self, is_running, row=None): def vm_state_change(self, is_running, row=None):
self.state_item.set_state(is_running) self.state_item.set_state(is_running)
@ -385,13 +385,6 @@ class VMRow:
self.checkbox = None self.checkbox = None
def is_vm_running(vm):
try:
return vm.is_running()
except exc.QubesPropertyAccessError:
return False
def main(): def main():
utils.run_asynchronous(TemplateManagerWindow) utils.run_asynchronous(TemplateManagerWindow)

View File

@ -54,7 +54,7 @@ def is_internal(vm):
try: try:
return (vm.klass == 'AdminVM' return (vm.klass == 'AdminVM'
or vm.features.get('internal', False)) or vm.features.get('internal', False))
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
return False return False
@ -63,7 +63,7 @@ def is_running(vm, default_state):
insufficient permissions to deteremine that.""" insufficient permissions to deteremine that."""
try: try:
return vm.is_running() return vm.is_running()
except exc.QubesPropertyAccessError: except exc.QubesDaemonAccessError:
return default_state return default_state
@ -107,7 +107,7 @@ class SizeSpinBox(QtWidgets.QSpinBox):
def get_feature(vm, feature_name, default_value): def get_feature(vm, feature_name, default_value):
try: try:
return vm.features.get(feature_name, default_value) return vm.features.get(feature_name, default_value)
except exc.QubesDaemonCommunicationError: except exc.QubesDaemonAccessError:
return default_value return default_value
@ -186,7 +186,10 @@ def initialize_widget_for_property(
:return: :return:
""" """
if allow_default: if allow_default:
try:
default_property = holder.property_get_default(property_name) default_property = holder.property_get_default(property_name)
except exc.QubesDaemonAccessError:
default_property = "ERROR: unavailable"
if default_property is None: if default_property is None:
default_property = "none" default_property = "none"
choices.append( choices.append(
@ -194,7 +197,12 @@ def initialize_widget_for_property(
qubesadmin.DEFAULT)) qubesadmin.DEFAULT))
# calculate current (can be default) # calculate current (can be default)
if holder.property_is_default(property_name): try:
is_default = holder.property_is_default(property_name)
except exc.QubesDaemonAccessError:
is_default = False
if is_default:
current_value = qubesadmin.DEFAULT current_value = qubesadmin.DEFAULT
else: else:
current_value = getattr(holder, property_name) current_value = getattr(holder, property_name)

View File

@ -11,6 +11,9 @@ class QubesVMNotStartedError(BaseException):
class QubesPropertyAccessError(BaseException): class QubesPropertyAccessError(BaseException):
pass pass
class QubesDaemonAccessError(BaseException):
pass
class QubesNoSuchPropertyError(BaseException): class QubesNoSuchPropertyError(BaseException):
pass pass