diff --git a/icons/kill.png b/icons/kill.png
new file mode 100644
index 0000000..6072634
Binary files /dev/null and b/icons/kill.png differ
diff --git a/mainwindow.ui b/mainwindow.ui
index 03e1249..54a8165 100644
--- a/mainwindow.ui
+++ b/mainwindow.ui
@@ -267,6 +267,7 @@
+
@@ -318,7 +319,7 @@
Start/Resume VM
- Start/Resume a VM
+ Start/Resume selected VM
@@ -333,7 +334,7 @@
Pause VM
- Pause a running VM
+ Pause selected VM
@@ -348,7 +349,7 @@
Shutdown VM
- Shutdown a running VM
+ Shutdown selected VM
@@ -386,7 +387,7 @@
true
- true
+ false
@@ -553,6 +554,18 @@
State
+
+
+
+ :/killvm.png:/killvm.png
+
+
+ Kill VM
+
+
+ Kill selected VM
+
+
diff --git a/qubesmanager/main.py b/qubesmanager/main.py
index 12b42fe..3da1232 100755
--- a/qubesmanager/main.py
+++ b/qubesmanager/main.py
@@ -608,6 +608,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.context_menu.addAction(self.action_resumevm)
self.context_menu.addAction(self.action_pausevm)
self.context_menu.addAction(self.action_shutdownvm)
+ self.context_menu.addAction(self.action_killvm)
self.context_menu.addAction(self.action_appmenus)
self.context_menu.addAction(self.action_editfwrules)
self.context_menu.addAction(self.action_updatevm)
@@ -896,6 +897,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.action_resumevm.setEnabled(not vm.last_running)
self.action_pausevm.setEnabled(vm.last_running and vm.qid != 0)
self.action_shutdownvm.setEnabled(vm.last_running and vm.qid != 0)
+ self.action_killvm.setEnabled(vm.last_running and vm.qid != 0)
self.action_appmenus.setEnabled(not vm.is_netvm())
self.action_editfwrules.setEnabled(vm.is_networked() and not (vm.is_netvm() and not vm.is_proxyvm()))
self.action_updatevm.setEnabled(vm.is_updateable() or vm.qid == 0)
@@ -905,6 +907,7 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
self.action_resumevm.setEnabled(False)
self.action_pausevm.setEnabled(False)
self.action_shutdownvm.setEnabled(False)
+ self.action_killvm.setEnabled(False)
self.action_appmenus.setEnabled(False)
self.action_editfwrules.setEnabled(False)
self.action_updatevm.setEnabled(False)
@@ -1170,6 +1173,28 @@ class VmManagerWindow(Ui_VmManagerWindow, QMainWindow):
QTimer.singleShot (vm_shutdown_timeout, self.shutdown_monitor[vm.qid].check_if_vm_has_shutdown)
+ @pyqtSlot(name='on_action_killvm_triggered')
+ def action_killvm_triggered(self):
+ vm = self.get_selected_vm()
+ assert vm.is_running()
+
+ reply = QMessageBox.question(None, "VM Kill Confirmation",
+ "Are you sure you want to kill the VM '{0}'?
"
+ "This will end (not shutdown!) all the running applications within this VM.".format(vm.name),
+ QMessageBox.Yes | QMessageBox.Cancel, QMessageBox.Cancel)
+
+ app.processEvents()
+
+ if reply == QMessageBox.Yes:
+ try:
+ vm.force_shutdown()
+ except Exception as ex:
+ QMessageBox.critical (None, "Error while killing VM!", "An exception ocurred while killing {0}.
ERROR: {1}".format(vm.name, ex))
+ return
+
+ trayIcon.showMessage ("Qubes Manager", "VM '{0}' killed!".format(vm.name), msecs=3000)
+
+
@pyqtSlot(name='on_action_settings_triggered')
def action_settings_triggered(self):
diff --git a/resources.qrc b/resources.qrc
index 7d34360..34add3b 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -35,9 +35,9 @@
icons/createvm.png
icons/removevm.png
icons/shutdownvm.png
+ icons/kill.png
icons/resumevm.png
icons/pausevm.png
- icons/showallvms.png
icons/showcpuload.png