Merge remote-tracking branch 'origin/pr/281'

* origin/pr/281:
  Tests suite fixes
  Use internal vm.shutdown_timeout
  Fix pylint warning
  Show all non halted vm's as running
  use force=True when restarting a netvm with connected vms
  Join all connected VM's in same warning
  Rewrite without cascade var
  Don't wait!
  First initiate shutdown for all vm's, then wait
  Fix wrong identation (thanks pylint)
  Avoid infite loop while waiting vm to shutdown
  Fix pylint warnings
  Cascade shutdown
这个提交包含在:
Marek Marczykowski-Górecki 2021-05-30 00:56:11 +02:00
当前提交 aaf99091ef
找不到此签名对应的密钥
GPG 密钥 ID: 063938BA42CFA724
共有 2 个文件被更改,包括 53 次插入26 次删除

查看文件

@ -493,17 +493,15 @@ class QubesTableModel(QAbstractTableModel):
return def_flags | Qt.ItemIsUserCheckable
return def_flags
vm_shutdown_timeout = 20000 # in msec
vm_restart_check_timeout = 1000 # in msec
class VmShutdownMonitor(QObject):
def __init__(self, vm, shutdown_time=vm_shutdown_timeout,
check_time=vm_restart_check_timeout,
def __init__(self, vm, check_time=vm_restart_check_timeout,
and_restart=False, caller=None):
QObject.__init__(self)
self.vm = vm
self.shutdown_time = shutdown_time
self.shutdown_timeout = vm.shutdown_timeout
self.check_time = check_time
self.and_restart = and_restart
self.shutdown_started = datetime.now()
@ -519,7 +517,7 @@ class VmShutdownMonitor(QObject):
def timeout_reached(self):
actual = datetime.now() - self.shutdown_started
allowed = timedelta(milliseconds=self.shutdown_time)
allowed = timedelta(seconds=self.shutdown_timeout)
return actual > allowed
@ -541,12 +539,12 @@ class VmShutdownMonitor(QObject):
msgbox.setText(self.tr(
"The Qube <b>'{0}'</b> hasn't shutdown within the last "
"{1} seconds, do you want to kill it?<br>").format(
vm.name, self.shutdown_time / 1000))
vm.name, self.shutdown_timeout))
kill_button = msgbox.addButton(
self.tr("Kill it!"), QMessageBox.YesRole)
wait_button = msgbox.addButton(
self.tr("Wait another {0} seconds...").format(
self.shutdown_time / 1000),
self.shutdown_timeout),
QMessageBox.NoRole)
ignore_button = msgbox.addButton(self.tr("Don't ask again"),
QMessageBox.RejectRole)
@ -668,7 +666,7 @@ class QubesProxyModel(QSortFilterProxyModel):
vm = self.sourceModel().data(index, Qt.UserRole)
if self.window.show_running.isChecked() and \
vm.state['power'] == 'Running':
vm.state['power'] != 'Halted':
return super().filterAcceptsRow(sourceRow, sourceParent)
if self.window.show_halted.isChecked() and \
vm.state['power'] == 'Halted':
@ -1407,24 +1405,52 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
if reply == QMessageBox.Yes:
self.shutdown_vm(vm)
def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout,
check_time=vm_restart_check_timeout, and_restart=False):
def get_connected_vms(self, vm, connected_vms):
for connected_vm in vm.connected_vms:
if connected_vm.is_running():
connected_vms.append(connected_vm)
self.get_connected_vms(connected_vm, connected_vms)
def shutdown_vm(self, vm, force=False, check_time=vm_restart_check_timeout,
and_restart=False):
try:
vm.shutdown()
connected_vms = []
if not and_restart:
self.get_connected_vms(vm, connected_vms)
if len(connected_vms) > 0:
reply = QMessageBox.question(
self, self.tr("Qube Shutdown Confirmation"),
self.tr("There are some qubes connected to <b>'{0}'</b>!"
"<br><small>Do you want to shutdown: </small>"
"<b>'{1}'</b>?").format(vm.name,
", ".join([x.name for x in connected_vms])),
QMessageBox.Yes | QMessageBox.Cancel)
if reply != QMessageBox.Yes:
return False
force = True
for connected_vm in connected_vms:
connected_vm.shutdown(force=force)
vm.shutdown(force=force)
except exc.QubesException as ex:
QMessageBox.warning(
self,
self.tr("Error shutting down Qube!"),
self.tr("ERROR: {0}").format(ex))
return
return False
self.shutdown_monitor[vm.qid] = VmShutdownMonitor(vm, shutdown_time,
check_time,
self.shutdown_monitor[vm.qid] = VmShutdownMonitor(vm, check_time,
and_restart, self)
# noinspection PyCallByClass,PyTypeChecker
QTimer.singleShot(check_time, self.shutdown_monitor[
vm.qid].check_if_vm_has_shutdown)
return True
# noinspection PyArgumentList
@pyqtSlot(name='on_action_restartvm_triggered')
def action_restartvm_triggered(self):
@ -1441,7 +1467,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
# in case the user shut down the VM in the meantime
try:
if manager_utils.is_running(vm, False):
self.shutdown_vm(vm, and_restart=True)
self.shutdown_vm(vm, force=True, and_restart=True)
else:
self.start_vm(vm)
except exc.QubesException as ex:

查看文件

@ -457,11 +457,10 @@ class QubeManagerTest(unittest.TestCase):
with unittest.mock.patch.object(selected_vm, 'shutdown')\
as mock_shutdown:
self.dialog.action_shutdownvm.trigger()
mock_shutdown.assert_called_once_with()
mock_shutdown.assert_called_once_with(force=False)
mock_monitor.assert_called_once_with(
selected_vm,
unittest.mock.ANY, unittest.mock.ANY,
unittest.mock.ANY, unittest.mock.ANY)
selected_vm, unittest.mock.ANY, unittest.mock.ANY,
unittest.mock.ANY)
mock_timer.assert_called_once_with(unittest.mock.ANY,
unittest.mock.ANY)
@ -546,10 +545,9 @@ class QubeManagerTest(unittest.TestCase):
with unittest.mock.patch.object(selected_vm, 'shutdown')\
as mock_shutdown:
action.trigger()
mock_shutdown.assert_called_once_with()
mock_shutdown.assert_called_once_with(force=True)
mock_monitor.assert_called_once_with(
selected_vm, unittest.mock.ANY,
unittest.mock.ANY, True, unittest.mock.ANY)
selected_vm, 1000, True, unittest.mock.ANY)
@unittest.mock.patch('qubesmanager.qube_manager.StartVMThread')
@unittest.mock.patch("PyQt5.QtWidgets.QMessageBox.question",
@ -1484,7 +1482,7 @@ class QubeManagerTest(unittest.TestCase):
for row in range(self.dialog.table.model().rowCount()):
template = self._get_table_item(row, "Template")
vm = self._get_table_vm(row)
if template != 'AdminVM' and \
if template != 'AdminVM' and not vm.provides_network and \
(running is None
or (running and vm.is_running())
or (not running and not vm.is_running())):
@ -1691,8 +1689,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True
mock_vm.start_time = datetime.datetime.now().timestamp() - 3000
mock_vm.shutdown_timeout = 60
monitor = qube_manager.VmShutdownMonitor(mock_vm, shutdown_time=1)
monitor = qube_manager.VmShutdownMonitor(mock_vm)
time.sleep(3)
monitor.check_if_vm_has_shutdown()
@ -1708,8 +1707,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True
mock_vm.start_time = datetime.datetime.now().timestamp() - 3000
mock_vm.shutdown_timeout = 1
monitor = qube_manager.VmShutdownMonitor(mock_vm, shutdown_time=1)
monitor = qube_manager.VmShutdownMonitor(mock_vm)
time.sleep(3)
monitor.restart_vm_if_needed = unittest.mock.Mock()
@ -1725,8 +1725,9 @@ class VMShutdownMonitorTest(unittest.TestCase):
mock_vm = unittest.mock.Mock()
mock_vm.is_running.return_value = True
mock_vm.start_time = datetime.datetime.now().timestamp() - 3000
mock_vm.shutdown_timeout = 30
monitor = qube_manager.VmShutdownMonitor(mock_vm, shutdown_time=3000)
monitor = qube_manager.VmShutdownMonitor(mock_vm)
time.sleep(1)
monitor.check_if_vm_has_shutdown()