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
This commit is contained in:
commit
aaf99091ef
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user