parent
8da27e646f
commit
7cd1afbb3c
BIN
icons/restartvm.png
Normal file
BIN
icons/restartvm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -320,6 +320,7 @@
|
|||||||
<addaction name="action_resumevm"/>
|
<addaction name="action_resumevm"/>
|
||||||
<addaction name="action_pausevm"/>
|
<addaction name="action_pausevm"/>
|
||||||
<addaction name="action_shutdownvm"/>
|
<addaction name="action_shutdownvm"/>
|
||||||
|
<addaction name="action_restartvm"/>
|
||||||
<addaction name="action_killvm"/>
|
<addaction name="action_killvm"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="action_settings"/>
|
<addaction name="action_settings"/>
|
||||||
@ -369,6 +370,7 @@
|
|||||||
<addaction name="action_resumevm"/>
|
<addaction name="action_resumevm"/>
|
||||||
<addaction name="action_pausevm"/>
|
<addaction name="action_pausevm"/>
|
||||||
<addaction name="action_shutdownvm"/>
|
<addaction name="action_shutdownvm"/>
|
||||||
|
<addaction name="action_restartvm"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
<addaction name="action_settings"/>
|
<addaction name="action_settings"/>
|
||||||
<addaction name="action_editfwrules"/>
|
<addaction name="action_editfwrules"/>
|
||||||
@ -455,6 +457,21 @@
|
|||||||
<string>Shutdown selected VM</string>
|
<string>Shutdown selected VM</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="action_restartvm">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<property name="icon">
|
||||||
|
<iconset resource="resources.qrc">
|
||||||
|
<normaloff>:/restartvm.png</normaloff>:/restartvm.png</iconset>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Restart VM</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Restart selected VM</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
<action name="action_appmenus">
|
<action name="action_appmenus">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
|
@ -240,36 +240,48 @@ class VmRowInTable(object):
|
|||||||
|
|
||||||
|
|
||||||
vm_shutdown_timeout = 20000 # in msec
|
vm_shutdown_timeout = 20000 # in msec
|
||||||
|
vm_restart_check_timeout= 1000 # in msec
|
||||||
|
|
||||||
|
|
||||||
class VmShutdownMonitor(QObject):
|
class VmShutdownMonitor(QObject):
|
||||||
def __init__(self, vm, shutdown_time=vm_shutdown_timeout):
|
def __init__(self, vm, shutdown_time=vm_shutdown_timeout, check_time=vm_restart_check_timeout, and_restart=False, caller=None):
|
||||||
QObject.__init__(self)
|
QObject.__init__(self)
|
||||||
self.vm = vm
|
self.vm = vm
|
||||||
self.shutdown_time = shutdown_time
|
self.shutdown_time = shutdown_time
|
||||||
|
self.check_time = check_time
|
||||||
|
self.and_restart = and_restart
|
||||||
|
self.shutdown_started = datetime.now()
|
||||||
|
self.caller = caller
|
||||||
|
|
||||||
def check_if_vm_has_shutdown(self):
|
def check_if_vm_has_shutdown(self):
|
||||||
vm = self.vm
|
vm = self.vm
|
||||||
vm_start_time = vm.get_start_time()
|
vm_start_time = vm.get_start_time()
|
||||||
if not vm.is_running() or (
|
if vm.is_running() and vm_start_time and vm_start_time < self.shutdown_started:
|
||||||
vm_start_time and vm_start_time >= datetime.now() -
|
if (datetime.now()-self.shutdown_started) > timedelta(milliseconds=self.shutdown_time):
|
||||||
timedelta(0, self.shutdown_time / 1000)):
|
reply = QMessageBox.question(
|
||||||
return
|
None, "VM Shutdown",
|
||||||
|
"The VM <b>'{0}'</b> hasn't shutdown within the last {1} seconds, "
|
||||||
reply = QMessageBox.question(
|
"do you want to kill it?<br>".format(
|
||||||
None, "VM Shutdown",
|
vm.name, self.shutdown_time / 1000),
|
||||||
"The VM <b>'{0}'</b> hasn't shutdown within the last {1} seconds, "
|
"Kill it!",
|
||||||
"do you want to kill it?<br>".format(
|
"Wait another {0} seconds...".format(
|
||||||
vm.name, self.shutdown_time / 1000),
|
self.shutdown_time / 1000))
|
||||||
"Kill it!",
|
if reply == 0:
|
||||||
"Wait another {0} seconds...".format(
|
vm.force_shutdown()
|
||||||
self.shutdown_time / 1000))
|
if self.and_restart:
|
||||||
if reply == 0:
|
if self.caller:
|
||||||
vm.force_shutdown()
|
self.caller.start_vm(vm)
|
||||||
|
else:
|
||||||
|
# noinspection PyTypeChecker,PyCallByClass
|
||||||
|
self.shutdown_started=datetime.now()
|
||||||
|
QTimer.singleShot(self.check_time, self.check_if_vm_has_shutdown)
|
||||||
|
else:
|
||||||
|
QTimer.singleShot(self.check_time, self.check_if_vm_has_shutdown)
|
||||||
else:
|
else:
|
||||||
# noinspection PyTypeChecker,PyCallByClass
|
|
||||||
QTimer.singleShot(self.shutdown_time, self.check_if_vm_has_shutdown)
|
|
||||||
|
|
||||||
|
if self.and_restart:
|
||||||
|
if self.caller:
|
||||||
|
self.caller.start_vm(vm)
|
||||||
|
|
||||||
class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
||||||
row_height = 30
|
row_height = 30
|
||||||
@ -408,6 +420,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
self.context_menu.addAction(self.action_startvm_tools_install)
|
self.context_menu.addAction(self.action_startvm_tools_install)
|
||||||
self.context_menu.addAction(self.action_pausevm)
|
self.context_menu.addAction(self.action_pausevm)
|
||||||
self.context_menu.addAction(self.action_shutdownvm)
|
self.context_menu.addAction(self.action_shutdownvm)
|
||||||
|
self.context_menu.addAction(self.action_restartvm)
|
||||||
self.context_menu.addAction(self.action_killvm)
|
self.context_menu.addAction(self.action_killvm)
|
||||||
self.context_menu.addSeparator()
|
self.context_menu.addSeparator()
|
||||||
|
|
||||||
@ -879,6 +892,10 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
vm.last_running and
|
vm.last_running and
|
||||||
vm.last_power_state != "Paused" and
|
vm.last_power_state != "Paused" and
|
||||||
vm.qid != 0)
|
vm.qid != 0)
|
||||||
|
self.action_restartvm.setEnabled(
|
||||||
|
vm.last_running and
|
||||||
|
vm.last_power_state != "Paused" and
|
||||||
|
vm.qid != 0)
|
||||||
self.action_killvm.setEnabled((vm.last_running or
|
self.action_killvm.setEnabled((vm.last_running or
|
||||||
vm.last_power_state == "Paused") and
|
vm.last_power_state == "Paused") and
|
||||||
vm.qid != 0)
|
vm.qid != 0)
|
||||||
@ -905,6 +922,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
self.action_resumevm.setEnabled(False)
|
self.action_resumevm.setEnabled(False)
|
||||||
self.action_pausevm.setEnabled(False)
|
self.action_pausevm.setEnabled(False)
|
||||||
self.action_shutdownvm.setEnabled(False)
|
self.action_shutdownvm.setEnabled(False)
|
||||||
|
self.action_restartvm.setEnabled(False)
|
||||||
self.action_killvm.setEnabled(False)
|
self.action_killvm.setEnabled(False)
|
||||||
self.action_appmenus.setEnabled(False)
|
self.action_appmenus.setEnabled(False)
|
||||||
self.action_editfwrules.setEnabled(False)
|
self.action_editfwrules.setEnabled(False)
|
||||||
@ -1129,6 +1147,10 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
"ERROR: {0}".format(ex))
|
"ERROR: {0}".format(ex))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
self.start_vm(vm)
|
||||||
|
|
||||||
|
def start_vm(self, vm):
|
||||||
assert not vm.is_running()
|
assert not vm.is_running()
|
||||||
thread_monitor = ThreadMonitor()
|
thread_monitor = ThreadMonitor()
|
||||||
thread = threading.Thread(target=self.do_start_vm,
|
thread = threading.Thread(target=self.do_start_vm,
|
||||||
@ -1238,7 +1260,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
if reply == QMessageBox.Yes:
|
if reply == QMessageBox.Yes:
|
||||||
self.shutdown_vm(vm)
|
self.shutdown_vm(vm)
|
||||||
|
|
||||||
def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout):
|
def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout, check_time=vm_restart_check_timeout, and_restart=False):
|
||||||
try:
|
try:
|
||||||
vm.shutdown()
|
vm.shutdown()
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
@ -1249,11 +1271,31 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
|
|||||||
trayIcon.showMessage("VM '{0}' is shutting down...".format(vm.name),
|
trayIcon.showMessage("VM '{0}' is shutting down...".format(vm.name),
|
||||||
msecs=3000)
|
msecs=3000)
|
||||||
|
|
||||||
self.shutdown_monitor[vm.qid] = VmShutdownMonitor(vm, shutdown_time)
|
self.shutdown_monitor[vm.qid] = VmShutdownMonitor(vm, shutdown_time, check_time, and_restart, self)
|
||||||
# noinspection PyCallByClass,PyTypeChecker
|
# noinspection PyCallByClass,PyTypeChecker
|
||||||
QTimer.singleShot(shutdown_time, self.shutdown_monitor[
|
QTimer.singleShot(check_time, self.shutdown_monitor[
|
||||||
vm.qid].check_if_vm_has_shutdown)
|
vm.qid].check_if_vm_has_shutdown)
|
||||||
|
|
||||||
|
|
||||||
|
@pyqtSlot(name='on_action_restartvm_triggered')
|
||||||
|
def action_restartvm_triggered(self):
|
||||||
|
vm = self.get_selected_vm()
|
||||||
|
assert vm.is_running()
|
||||||
|
|
||||||
|
self.blk_manager.check_if_serves_as_backend(vm)
|
||||||
|
|
||||||
|
reply = QMessageBox.question(
|
||||||
|
None, "VM Restart Confirmation",
|
||||||
|
"Are you sure you want to restart the VM <b>'{0}'</b>?<br>"
|
||||||
|
"<small>This will shutdown all the running applications "
|
||||||
|
"within this VM.</small>".format(vm.name),
|
||||||
|
QMessageBox.Yes | QMessageBox.Cancel)
|
||||||
|
|
||||||
|
app.processEvents()
|
||||||
|
|
||||||
|
if reply == QMessageBox.Yes:
|
||||||
|
self.shutdown_vm(vm, and_restart=True)
|
||||||
|
|
||||||
@pyqtSlot(name='on_action_killvm_triggered')
|
@pyqtSlot(name='on_action_killvm_triggered')
|
||||||
def action_killvm_triggered(self):
|
def action_killvm_triggered(self):
|
||||||
vm = self.get_selected_vm()
|
vm = self.get_selected_vm()
|
||||||
|
@ -48,5 +48,6 @@
|
|||||||
<file alias="pausevm.png">icons/pausevm.png</file>
|
<file alias="pausevm.png">icons/pausevm.png</file>
|
||||||
<file alias="showcpuload.png">icons/showcpuload.png</file>
|
<file alias="showcpuload.png">icons/showcpuload.png</file>
|
||||||
<file alias="mic.png">icons/mic.png</file>
|
<file alias="mic.png">icons/mic.png</file>
|
||||||
|
<file alias="restartvm.png">icons/restartvm.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
Loading…
Reference in New Issue
Block a user