From 7ddd37deab56aa304ce975b7a40559eede063edf Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 2 Mar 2011 12:51:29 +0100 Subject: [PATCH 01/15] Suport for commit template changes --- qubesmanager/main.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 58cf124..7fd5296 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -319,8 +319,8 @@ class VmManagerWindow(QMainWindow): self.action_shutdownvm = self.createAction ("Shutdown VM", slot=self.shutdown_vm, icon="shutdownvm", tip="Shutdown a running VM") - self.action_updatevm = self.createAction ("Update VM", slot=None, - icon="updateable", tip="Update VM (only for 'updateable' VMs, e.g. templates)") + self.action_updatevm = self.createAction ("Commit VM changes", slot=self.update_vm, + icon="updateable", tip="Commit changes to template (only for 'updateable' template VMs); VM must be stopped") self.action_showallvms = self.createAction ("Show/Hide Inactive VMs", slot=None, checkable=True, icon="showallvms", tip="Show/Hide Inactive VMs") @@ -491,6 +491,7 @@ class VmManagerWindow(QMainWindow): #self.action_resumevm.setEnabled(not vm.is_running()) #self.action_pausevm.setEnabled(vm.is_running() and vm.qid != 0) self.action_shutdownvm.setEnabled(vm.is_running() and vm.qid != 0) + self.action_updatevm.setEnabled(vm.is_updateable() and not vm.is_running()) def closeEvent (self, event): self.hide() @@ -681,6 +682,15 @@ class VmManagerWindow(QMainWindow): self.shutdown_monitor[vm.qid] = VmShutdownMonitor (vm) QTimer.singleShot (vm_shutdown_timeout, self.shutdown_monitor[vm.qid].check_if_vm_has_shutdown) + def update_vm(self): + vm = self.get_selected_vm() + + try: + vm.commit_changes(); + except Exception as ex: + QMessageBox.warning (None, "Error commiting changes!", "ERROR: {0}".format(ex)) + return + def showcpuload(self): pass From f7e4a0f060b2a81bf638d20ccd82e68aed48b8f9 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 2 Mar 2011 14:42:11 +0100 Subject: [PATCH 02/15] Implement start button action --- qubesmanager/main.py | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 7fd5296..068fc23 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -42,6 +42,8 @@ import subprocess import time import threading +qubes_guid_path = '/usr/bin/qubes_guid' + class QubesConfigFileWatcher(ProcessEvent): def __init__ (self, update_func): self.update_func = update_func @@ -488,7 +490,7 @@ class VmManagerWindow(QMainWindow): # Update available actions: self.action_removevm.setEnabled(not vm.installed_by_rpm and not vm.is_running()) - #self.action_resumevm.setEnabled(not vm.is_running()) + self.action_resumevm.setEnabled(not vm.is_running()) #self.action_pausevm.setEnabled(vm.is_running() and vm.qid != 0) self.action_shutdownvm.setEnabled(vm.is_running() and vm.qid != 0) self.action_updatevm.setEnabled(vm.is_updateable() and not vm.is_running()) @@ -655,7 +657,20 @@ class VmManagerWindow(QMainWindow): thread_monitor.set_finished() def resume_vm(self): - pass + vm = self.get_selected_vm() + assert not vm.is_running() + + try: + vm.verify_files() + xid = vm.start() + except (IOError, OSError, QubesException) as err: + QMessageBox.warning (None, "Error starting VM!", "ERROR: {0}".format(err)) + return + + retcode = subprocess.call ([qubes_guid_path, "-d", str(xid), "-c", vm.label.color, "-i", vm.label.icon, "-l", str(vm.label.index)]) + if (retcode != 0): + QMessageBox.warning (None, "Error starting VM!", "ERROR: Cannot start qubes_guid!") + return def pause_vm(self): pass From eb607cead6de8f1cf1f3cb28e2a83ab4af894075 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 2 Mar 2011 14:50:21 +0100 Subject: [PATCH 03/15] Implement pause button --- qubesmanager/main.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 068fc23..3555c4f 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -673,7 +673,13 @@ class VmManagerWindow(QMainWindow): return def pause_vm(self): - pass + vm = self.get_selected_vm() + assert vm.is_running() + try: + subprocess.check_call (["/usr/sbin/xm", "pause", vm.name]) + except Exception as ex: + QMessageBox.warning (None, "Error pausing VM!", "ERROR: {0}".format(ex)) + return def shutdown_vm(self): vm = self.get_selected_vm() From 2f438739c82e5d9b7317126c6341f5dfa8218fc0 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 2 Mar 2011 14:52:13 +0100 Subject: [PATCH 04/15] Enable pause button --- qubesmanager/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 3555c4f..5c4b187 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -491,7 +491,7 @@ class VmManagerWindow(QMainWindow): self.action_removevm.setEnabled(not vm.installed_by_rpm and not vm.is_running()) self.action_resumevm.setEnabled(not vm.is_running()) - #self.action_pausevm.setEnabled(vm.is_running() and vm.qid != 0) + self.action_pausevm.setEnabled(vm.is_running() and vm.qid != 0) self.action_shutdownvm.setEnabled(vm.is_running() and vm.qid != 0) self.action_updatevm.setEnabled(vm.is_updateable() and not vm.is_running()) From 1b22d30643651c7a80996f75a1ce223261fa94e5 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 2 Mar 2011 14:53:27 +0100 Subject: [PATCH 05/15] Add compiled python scripts to rpm --- rpm_spec/qmgr.spec | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rpm_spec/qmgr.spec b/rpm_spec/qmgr.spec index 34b22a7..6b5f24f 100644 --- a/rpm_spec/qmgr.spec +++ b/rpm_spec/qmgr.spec @@ -22,16 +22,18 @@ The Graphical Qubes VM Manager. %build make res +python -m compileall qubesmanager +python -O -m compileall qubesmanager %install mkdir -p $RPM_BUILD_ROOT/usr/bin/ cp qubes-manager $RPM_BUILD_ROOT/usr/bin mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager/ -cp qubesmanager/main.py $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager -cp qubesmanager/qrc_resources.py $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager -cp qubesmanager/__init__.py $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager -cp qubesmanager/ui_newappvmdlg.py $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/main.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/qrc_resources.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/__init__.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/ui_newappvmdlg.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager mkdir -p $RPM_BUILD_ROOT/usr/share/applications cp qubes-manager.desktop $RPM_BUILD_ROOT/usr/share/applications From ec0a9ceae002e73408b2243db94e4b7581162f10 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sat, 5 Mar 2011 15:11:32 +0100 Subject: [PATCH 06/15] Add UI python files to gitignore --- qubesmanager/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/qubesmanager/.gitignore b/qubesmanager/.gitignore index f580b22..50937f1 100644 --- a/qubesmanager/.gitignore +++ b/qubesmanager/.gitignore @@ -1,2 +1,4 @@ qrc_resources.py ui_newappvmdlg.py +ui_editfwrulesdlg.py +ui_newfwruledlg.py From 7e1dd66c2488701edce647ee8d5da95e5700b964 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sat, 5 Mar 2011 15:12:34 +0100 Subject: [PATCH 07/15] Fix typo 'templete' --- qubesmanager/main.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 0362b73..e07a41b 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -75,7 +75,7 @@ class VmStatusIcon(QLabel): icon = QIcon (":/dom0.png") elif vm.is_appvm(): icon = QIcon (vm.label.icon_path) - elif vm.is_templete(): + elif vm.is_template(): icon = QIcon (":/templatevm.png") elif vm.is_netvm(): icon = QIcon (":/netvm.png") @@ -107,7 +107,7 @@ class VmInfoWidget (QWidget): if vm.is_appvm() or vm.is_disposablevm(): label_tmpl = QLabel ("" + vm.template_vm.name + "") - elif vm.is_templete(): + elif vm.is_template(): label_tmpl = QLabel ("TemplateVM") elif vm.qid == 0: label_tmpl = QLabel ("AdminVM") @@ -444,7 +444,7 @@ class VmManagerWindow(QMainWindow): # Now, the templates... for tvm in vms_list: - if tvm.is_templete(): + if tvm.is_template(): vms_to_display.append (tvm) label_list = QubesVmLabels.values() @@ -524,7 +524,7 @@ class VmManagerWindow(QMainWindow): dialog.vmlabel.insertItem(i, label.name) dialog.vmlabel.setItemIcon (i, QIcon(label.icon_path)) - template_vm_list = [vm for vm in self.qvm_collection.values() if vm.is_templete()] + template_vm_list = [vm for vm in self.qvm_collection.values() if vm.is_template()] default_index = 0 for (i, vm) in enumerate(template_vm_list): @@ -602,7 +602,7 @@ class VmManagerWindow(QMainWindow): self.qvm_collection.load() self.qvm_collection.unlock_db() - if vm.is_templete(): + if vm.is_template(): dependent_vms = self.qvm_collection.get_vms_based_on(vm.qid) if len(dependent_vms) > 0: QMessageBox.warning (None, "Warning!", @@ -647,7 +647,7 @@ class VmManagerWindow(QMainWindow): self.qvm_collection.load() #TODO: the following two conditions should really be checked by qvm_collection.pop() overload... - if vm.is_templete() and qvm_collection.default_template_qid == vm.qid: + if vm.is_template() and qvm_collection.default_template_qid == vm.qid: qvm_collection.default_template_qid = None if vm.is_netvm() and qvm_collection.default_netvm_qid == vm.qid: qvm_collection.default_netvm_qid = None From aeb1fb66f8113bc4467ba7cc234155ab7c781c9e Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sun, 6 Mar 2011 19:54:22 +0100 Subject: [PATCH 08/15] Remove generated files (ui) --- qubesmanager/ui_editfwrulesdlg.py | 66 ----------------------- qubesmanager/ui_newfwruledlg.py | 88 ------------------------------- 2 files changed, 154 deletions(-) delete mode 100644 qubesmanager/ui_editfwrulesdlg.py delete mode 100644 qubesmanager/ui_newfwruledlg.py diff --git a/qubesmanager/ui_editfwrulesdlg.py b/qubesmanager/ui_editfwrulesdlg.py deleted file mode 100644 index 0d179b4..0000000 --- a/qubesmanager/ui_editfwrulesdlg.py +++ /dev/null @@ -1,66 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'editfwrulesdlg.ui' -# -# Created: Wed Feb 16 20:55:59 2011 -# by: PyQt4 UI code generator 4.7.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_EditFwRulesDlg(object): - def setupUi(self, EditFwRulesDlg): - EditFwRulesDlg.setObjectName("EditFwRulesDlg") - EditFwRulesDlg.resize(500, 280) - self.verticalLayout_3 = QtGui.QVBoxLayout(EditFwRulesDlg) - self.verticalLayout_3.setObjectName("verticalLayout_3") - self.horizontalLayout = QtGui.QHBoxLayout() - self.horizontalLayout.setSizeConstraint(QtGui.QLayout.SetMaximumSize) - self.horizontalLayout.setObjectName("horizontalLayout") - self.rulesTreeView = QtGui.QTreeView(EditFwRulesDlg) - self.rulesTreeView.setRootIsDecorated(False) - self.rulesTreeView.setUniformRowHeights(False) - self.rulesTreeView.setItemsExpandable(False) - self.rulesTreeView.setAllColumnsShowFocus(True) - self.rulesTreeView.setExpandsOnDoubleClick(True) - self.rulesTreeView.setObjectName("rulesTreeView") - self.rulesTreeView.header().setDefaultSectionSize(40) - self.rulesTreeView.header().setStretchLastSection(False) - self.horizontalLayout.addWidget(self.rulesTreeView) - self.verticalLayout = QtGui.QVBoxLayout() - self.verticalLayout.setObjectName("verticalLayout") - self.newRuleButton = QtGui.QPushButton(EditFwRulesDlg) - self.newRuleButton.setObjectName("newRuleButton") - self.verticalLayout.addWidget(self.newRuleButton) - self.editRuleButton = QtGui.QPushButton(EditFwRulesDlg) - self.editRuleButton.setObjectName("editRuleButton") - self.verticalLayout.addWidget(self.editRuleButton) - self.deleteRuleButton = QtGui.QPushButton(EditFwRulesDlg) - self.deleteRuleButton.setObjectName("deleteRuleButton") - self.verticalLayout.addWidget(self.deleteRuleButton) - spacerItem = QtGui.QSpacerItem(20, 40, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Expanding) - self.verticalLayout.addItem(spacerItem) - self.horizontalLayout.addLayout(self.verticalLayout) - self.verticalLayout_3.addLayout(self.horizontalLayout) - self.buttonBox = QtGui.QDialogButtonBox(EditFwRulesDlg) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) - self.buttonBox.setObjectName("buttonBox") - self.verticalLayout_3.addWidget(self.buttonBox) - - self.retranslateUi(EditFwRulesDlg) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), EditFwRulesDlg.reject) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), EditFwRulesDlg.accept) - QtCore.QMetaObject.connectSlotsByName(EditFwRulesDlg) - EditFwRulesDlg.setTabOrder(self.newRuleButton, self.editRuleButton) - EditFwRulesDlg.setTabOrder(self.editRuleButton, self.deleteRuleButton) - EditFwRulesDlg.setTabOrder(self.deleteRuleButton, self.rulesTreeView) - EditFwRulesDlg.setTabOrder(self.rulesTreeView, self.buttonBox) - - def retranslateUi(self, EditFwRulesDlg): - EditFwRulesDlg.setWindowTitle(QtGui.QApplication.translate("EditFwRulesDlg", "Edit Firewall Rules", None, QtGui.QApplication.UnicodeUTF8)) - self.newRuleButton.setText(QtGui.QApplication.translate("EditFwRulesDlg", "&New", None, QtGui.QApplication.UnicodeUTF8)) - self.editRuleButton.setText(QtGui.QApplication.translate("EditFwRulesDlg", "&Edit", None, QtGui.QApplication.UnicodeUTF8)) - self.deleteRuleButton.setText(QtGui.QApplication.translate("EditFwRulesDlg", "&Delete", None, QtGui.QApplication.UnicodeUTF8)) - diff --git a/qubesmanager/ui_newfwruledlg.py b/qubesmanager/ui_newfwruledlg.py deleted file mode 100644 index 5081e55..0000000 --- a/qubesmanager/ui_newfwruledlg.py +++ /dev/null @@ -1,88 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file 'newfwruledlg.ui' -# -# Created: Wed Feb 16 20:55:59 2011 -# by: PyQt4 UI code generator 4.7.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt4 import QtCore, QtGui - -class Ui_NewFwRuleDlg(object): - def setupUi(self, NewFwRuleDlg): - NewFwRuleDlg.setObjectName("NewFwRuleDlg") - NewFwRuleDlg.setWindowModality(QtCore.Qt.NonModal) - NewFwRuleDlg.resize(311, 202) - NewFwRuleDlg.setModal(True) - self.buttonBox = QtGui.QDialogButtonBox(NewFwRuleDlg) - self.buttonBox.setGeometry(QtCore.QRect(30, 160, 271, 32)) - self.buttonBox.setOrientation(QtCore.Qt.Horizontal) - self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok) - self.buttonBox.setObjectName("buttonBox") - self.label = QtGui.QLabel(NewFwRuleDlg) - self.label.setGeometry(QtCore.QRect(10, 10, 62, 17)) - self.label.setObjectName("label") - self.groupBox = QtGui.QGroupBox(NewFwRuleDlg) - self.groupBox.setGeometry(QtCore.QRect(10, 40, 291, 121)) - self.groupBox.setTitle("") - self.groupBox.setObjectName("groupBox") - self.label_2 = QtGui.QLabel(self.groupBox) - self.label_2.setGeometry(QtCore.QRect(10, 10, 62, 17)) - self.label_2.setObjectName("label_2") - self.label_3 = QtGui.QLabel(self.groupBox) - self.label_3.setGeometry(QtCore.QRect(190, 10, 62, 17)) - self.label_3.setObjectName("label_3") - self.allowCheckBox = QtGui.QCheckBox(self.groupBox) - self.allowCheckBox.setGeometry(QtCore.QRect(200, 80, 71, 23)) - sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed) - sizePolicy.setHorizontalStretch(0) - sizePolicy.setVerticalStretch(0) - sizePolicy.setHeightForWidth(self.allowCheckBox.sizePolicy().hasHeightForWidth()) - self.allowCheckBox.setSizePolicy(sizePolicy) - self.allowCheckBox.setObjectName("allowCheckBox") - self.addressEdit = QtGui.QLineEdit(self.groupBox) - self.addressEdit.setGeometry(QtCore.QRect(10, 30, 171, 27)) - self.addressEdit.setObjectName("addressEdit") - self.label_4 = QtGui.QLabel(self.groupBox) - self.label_4.setGeometry(QtCore.QRect(10, 62, 31, 21)) - self.label_4.setObjectName("label_4") - self.label_5 = QtGui.QLabel(self.groupBox) - self.label_5.setGeometry(QtCore.QRect(123, 62, 16, 21)) - self.label_5.setObjectName("label_5") - self.netmaskComboBox = QtGui.QComboBox(self.groupBox) - self.netmaskComboBox.setGeometry(QtCore.QRect(190, 30, 84, 27)) - self.netmaskComboBox.setObjectName("netmaskComboBox") - self.portBeginSpinBox = QtGui.QSpinBox(self.groupBox) - self.portBeginSpinBox.setGeometry(QtCore.QRect(50, 60, 71, 27)) - self.portBeginSpinBox.setMaximum(65535) - self.portBeginSpinBox.setProperty("value", 0) - self.portBeginSpinBox.setObjectName("portBeginSpinBox") - self.portEndSpinBox = QtGui.QSpinBox(self.groupBox) - self.portEndSpinBox.setGeometry(QtCore.QRect(130, 60, 71, 27)) - self.portEndSpinBox.setMaximum(65535) - self.portEndSpinBox.setObjectName("portEndSpinBox") - self.nameEdit = QtGui.QLineEdit(NewFwRuleDlg) - self.nameEdit.setGeometry(QtCore.QRect(60, 4, 241, 27)) - self.nameEdit.setObjectName("nameEdit") - - self.retranslateUi(NewFwRuleDlg) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), NewFwRuleDlg.accept) - QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), NewFwRuleDlg.reject) - QtCore.QMetaObject.connectSlotsByName(NewFwRuleDlg) - NewFwRuleDlg.setTabOrder(self.nameEdit, self.addressEdit) - NewFwRuleDlg.setTabOrder(self.addressEdit, self.netmaskComboBox) - NewFwRuleDlg.setTabOrder(self.netmaskComboBox, self.portBeginSpinBox) - NewFwRuleDlg.setTabOrder(self.portBeginSpinBox, self.portEndSpinBox) - NewFwRuleDlg.setTabOrder(self.portEndSpinBox, self.allowCheckBox) - NewFwRuleDlg.setTabOrder(self.allowCheckBox, self.buttonBox) - - def retranslateUi(self, NewFwRuleDlg): - NewFwRuleDlg.setWindowTitle(QtGui.QApplication.translate("NewFwRuleDlg", "New Firewall Rule", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("NewFwRuleDlg", "Name", None, QtGui.QApplication.UnicodeUTF8)) - self.label_2.setText(QtGui.QApplication.translate("NewFwRuleDlg", "Address", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("NewFwRuleDlg", "Netmask", None, QtGui.QApplication.UnicodeUTF8)) - self.allowCheckBox.setText(QtGui.QApplication.translate("NewFwRuleDlg", "Allow", None, QtGui.QApplication.UnicodeUTF8)) - self.label_4.setText(QtGui.QApplication.translate("NewFwRuleDlg", "Port", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("NewFwRuleDlg", "-", None, QtGui.QApplication.UnicodeUTF8)) - From c4cb54ab59e3175dfdeaaf9f0fc56b13ce34b87d Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sun, 6 Mar 2011 19:54:42 +0100 Subject: [PATCH 09/15] Add firewall files to rpm --- rpm_spec/qmgr.spec | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/rpm_spec/qmgr.spec b/rpm_spec/qmgr.spec index 6b5f24f..603bc84 100644 --- a/rpm_spec/qmgr.spec +++ b/rpm_spec/qmgr.spec @@ -31,9 +31,12 @@ cp qubes-manager $RPM_BUILD_ROOT/usr/bin mkdir -p $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager/ cp qubesmanager/main.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/firewall.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager cp qubesmanager/qrc_resources.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager cp qubesmanager/__init__.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager cp qubesmanager/ui_newappvmdlg.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/ui_newfwruledlg.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager +cp qubesmanager/ui_editfwrulesdlg.py{,c,o} $RPM_BUILD_ROOT%{python_sitearch}/qubesmanager mkdir -p $RPM_BUILD_ROOT/usr/share/applications cp qubes-manager.desktop $RPM_BUILD_ROOT/usr/share/applications @@ -58,12 +61,21 @@ rm -rf $RPM_BUILD_ROOT %{python_sitearch}/qubesmanager/main.py %{python_sitearch}/qubesmanager/main.pyc %{python_sitearch}/qubesmanager/main.pyo +%{python_sitearch}/qubesmanager/firewall.py +%{python_sitearch}/qubesmanager/firewall.pyc +%{python_sitearch}/qubesmanager/firewall.pyo %{python_sitearch}/qubesmanager/qrc_resources.py %{python_sitearch}/qubesmanager/qrc_resources.pyc %{python_sitearch}/qubesmanager/qrc_resources.pyo %{python_sitearch}/qubesmanager/ui_newappvmdlg.py %{python_sitearch}/qubesmanager/ui_newappvmdlg.pyc %{python_sitearch}/qubesmanager/ui_newappvmdlg.pyo +%{python_sitearch}/qubesmanager/ui_newfwruledlg.py +%{python_sitearch}/qubesmanager/ui_newfwruledlg.pyc +%{python_sitearch}/qubesmanager/ui_newfwruledlg.pyo +%{python_sitearch}/qubesmanager/ui_editfwrulesdlg.py +%{python_sitearch}/qubesmanager/ui_editfwrulesdlg.pyc +%{python_sitearch}/qubesmanager/ui_editfwrulesdlg.pyo /usr/share/applications/qubes-manager.desktop From 161675cf6a65643ec7b33f38baca09b45e6d8b31 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Wed, 9 Mar 2011 15:26:27 +0100 Subject: [PATCH 10/15] Delete AppVM after failed create only if it was (partially) created. --- qubesmanager/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index e07a41b..864ca6e 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -570,6 +570,7 @@ class VmManagerWindow(QMainWindow): def do_create_appvm (self, vmname, label, template_vm, thread_monitor): + vm = None try: self.qvm_collection.lock_db_for_writing() self.qvm_collection.load() @@ -580,7 +581,8 @@ class VmManagerWindow(QMainWindow): self.qvm_collection.save() except Exception as ex: thread_monitor.set_error_msg (str(ex)) - vm.remove_from_disk() + if vm: + vm.remove_from_disk() finally: self.qvm_collection.unlock_db() From b9a536da0eb70a60ad24d70cb83b2b928c908a56 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 10 Mar 2011 14:16:33 +0100 Subject: [PATCH 11/15] Git ignores --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 0d20b64..7fbea01 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ *.pyc +*.pyo +*~ +rpm/ From 5fb1181159560853b2bd97021860a0d15d196a39 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Thu, 10 Mar 2011 18:09:52 +0100 Subject: [PATCH 12/15] Toggle manager window visibility on icon click --- qubesmanager/main.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 871d339..01ef475 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -853,7 +853,7 @@ class QubesTrayIcon(QSystemTrayIcon): # Handle the right click normally, i.e. display the context menu return else: - show_manager() + toggle_manager() def addActions(self, target, actions): for action in actions: @@ -883,6 +883,11 @@ class QubesTrayIcon(QSystemTrayIcon): def show_manager(): manager_window.show() +def toggle_manager(): + if manager_window.isVisible(): + manager_window.hide() + else: + manager_window.show() def exit_app(): notifier.stop() From c903e5f25c031792aa9204591465742c107e4f33 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sun, 13 Mar 2011 18:43:55 +0100 Subject: [PATCH 13/15] Template changes commit confirmation --- qubesmanager/main.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 01ef475..6137347 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -778,12 +778,21 @@ class VmManagerWindow(QMainWindow): def update_vm(self): vm = self.get_selected_vm() + assert not vm.is_running() - try: - vm.commit_changes(); - except Exception as ex: - QMessageBox.warning (None, "Error commiting changes!", "ERROR: {0}".format(ex)) - return + reply = QMessageBox.question(None, "VM Update Confirmation", + "Are you sure you want to commit template '{0}' changes?
" + "AppVMs will see the changes after restart.".format(vm.name), + QMessageBox.Yes | QMessageBox.Cancel) + + app.processEvents() + + if reply == QMessageBox.Yes: + try: + vm.commit_changes(); + except Exception as ex: + QMessageBox.warning (None, "Error commiting changes!", "ERROR: {0}".format(ex)) + return def showcpuload(self): self.__cpugraphs = self.action_showcpuload.isChecked() From 60a3d1753afdf62d5028d0881b4dd6fcb6170809 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Sun, 13 Mar 2011 18:46:27 +0100 Subject: [PATCH 14/15] Tray notify after comit template changes. --- qubesmanager/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 6137347..620c191 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -793,6 +793,7 @@ class VmManagerWindow(QMainWindow): except Exception as ex: QMessageBox.warning (None, "Error commiting changes!", "ERROR: {0}".format(ex)) return + trayIcon.showMessage ("Qubes Manager", "Changes to template '{0}' commited.".format(vm.name), msecs=3000) def showcpuload(self): self.__cpugraphs = self.action_showcpuload.isChecked() From 7228a3968ef3c220ddf09eeb390bb467be4e5616 Mon Sep 17 00:00:00 2001 From: Marek Marczykowski Date: Mon, 14 Mar 2011 19:29:37 +0100 Subject: [PATCH 15/15] fwvm -> proxyvm once again --- qubesmanager/firewall.py | 2 +- qubesmanager/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/qubesmanager/firewall.py b/qubesmanager/firewall.py index 47e4296..59af881 100644 --- a/qubesmanager/firewall.py +++ b/qubesmanager/firewall.py @@ -260,7 +260,7 @@ class QubesFirewallRulesModel(QAbstractItemModel): qvm_collection.unlock_db() for vm in qvm_collection.values(): - if vm.is_fwvm(): + if vm.is_proxyvm(): vm.write_iptables_xenstore_entry() def index(self, row, column, parent=QModelIndex()): diff --git a/qubesmanager/main.py b/qubesmanager/main.py index 620c191..926afdb 100755 --- a/qubesmanager/main.py +++ b/qubesmanager/main.py @@ -817,7 +817,7 @@ class VmManagerWindow(QMainWindow): qvm_collection.unlock_db() for vm in qvm_collection.values(): - if vm.is_fwvm(): + if vm.is_proxyvm(): error_file = "/local/domain/{0}/qubes_iptables_error".format(vm.get_xid()) error = subprocess.Popen(