From 27226171aa63d2dc830cc0beb2ac13f32cd42f5a Mon Sep 17 00:00:00 2001 From: Agnieszka Kostrzewa Date: Mon, 12 Mar 2012 15:54:16 +0100 Subject: [PATCH] Apply settings only if something was changed. --- qubesmanager/appmenu_select.py | 35 ++++++++++---- qubesmanager/firewall.py | 31 +++++++----- qubesmanager/settings.py | 87 +++++++++++++++------------------- 3 files changed, 82 insertions(+), 71 deletions(-) diff --git a/qubesmanager/appmenu_select.py b/qubesmanager/appmenu_select.py index 3c769ec..f70252d 100755 --- a/qubesmanager/appmenu_select.py +++ b/qubesmanager/appmenu_select.py @@ -92,28 +92,45 @@ class AppmenuSelectManager: break desktop_template.close() - whitelisted_appmenus = [a for a in available_appmenus if a[0] in whitelisted] + self.whitelisted_appmenus = [a for a in available_appmenus if a[0] in whitelisted] available_appmenus = [a for a in available_appmenus if a[0] not in whitelisted] for a in available_appmenus: self.app_list.available_list.addItem( AppListWidgetItem(a[1], a[0])) - for a in whitelisted_appmenus: + for a in self.whitelisted_appmenus: self.app_list.selected_list.addItem( AppListWidgetItem(a[1], a[0])) self.app_list.available_list.sortItems() self.app_list.selected_list.sortItems() def save_list_of_selected(self): - whitelisted = open(self.vm.dir_path + '/' + whitelisted_filename, 'w') + sth_changed = False + added = [] + for i in range(self.app_list.selected_list.count()): item = self.app_list.selected_list.item(i) - whitelisted.write(item.filename + '\n') - whitelisted.close() + if item.filename not in [ w[0] for w in self.whitelisted_appmenus]: + added.append(item) + + if self.app_list.selected_list.count() - len(added) < len(self.whitelisted_appmenus): #sth removed + sth_changed = True; + elif len(added) > 0: + sth_changed = True; + + if sth_changed == True: + whitelisted = open(self.vm.dir_path + '/' + whitelisted_filename, 'w') + for i in range(self.app_list.selected_list.count()): + item = self.app_list.selected_list.item(i) + whitelisted.write(item.filename + '\n') + whitelisted.close() + return True + else: + return False + - def save_appmenu_select_changes(self): - self.save_list_of_selected() - subprocess.check_call([qubes_appmenu_remove_cmd, self.vm.name]) - subprocess.check_call([qubes_appmenu_create_cmd, self.source_vm.appmenus_templates_dir, self.vm.name]) + if self.save_list_of_selected(): + subprocess.check_call([qubes_appmenu_remove_cmd, self.vm.name]) + subprocess.check_call([qubes_appmenu_create_cmd, self.source_vm.appmenus_templates_dir, self.vm.name]) diff --git a/qubesmanager/firewall.py b/qubesmanager/firewall.py index a2d0f46..0214bd0 100644 --- a/qubesmanager/firewall.py +++ b/qubesmanager/firewall.py @@ -191,6 +191,8 @@ class QubesFirewallRulesModel(QAbstractItemModel): self.__services.append( (service["name"], int(service["port"]),) ) f.close() + self.fw_changed = False + def sort(self, idx, order): from operator import attrgetter @@ -237,12 +239,15 @@ class QubesFirewallRulesModel(QAbstractItemModel): def get_vm_name(self): return self.__vm.name - def apply_rules(self): + def apply_rules(self, allow, dns, icmp): assert self.__vm is not None - conf = { "allow": self.allow, - "allowDns": self.allowDns, - "allowIcmp": self.allowIcmp, + if(self.allow != allow or self.allowDns != dns or self.allowIcmp != icmp): + self.fw_changed = True + + conf = { "allow": allow, + "allowDns": dns, + "allowIcmp": icmp, "rules": list() } @@ -257,16 +262,18 @@ class QubesFirewallRulesModel(QAbstractItemModel): } ) - self.__vm.write_firewall_conf(conf) + if self.fw_changed: + self.__vm.write_firewall_conf(conf) - qvm_collection = QubesVmCollection() - qvm_collection.lock_db_for_reading() - qvm_collection.load() - qvm_collection.unlock_db() + qvm_collection = QubesVmCollection() + qvm_collection.lock_db_for_reading() + qvm_collection.load() + qvm_collection.unlock_db() + + for vm in qvm_collection.values(): + if vm.is_proxyvm(): + vm.write_iptables_xenstore_entry() - for vm in qvm_collection.values(): - if vm.is_proxyvm(): - vm.write_iptables_xenstore_entry() def index(self, row, column, parent=QModelIndex()): if not self.hasIndex(row, column, parent): diff --git a/qubesmanager/settings.py b/qubesmanager/settings.py index 0027386..403bbbe 100644 --- a/qubesmanager/settings.py +++ b/qubesmanager/settings.py @@ -96,9 +96,6 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): self.newRuleButton.clicked.connect(self.new_rule_button_pressed) self.editRuleButton.clicked.connect(self.edit_rule_button_pressed) self.deleteRuleButton.clicked.connect(self.delete_rule_button_pressed) - self.policyAllowRadioButton.toggled.connect(self.policy_radio_toggled) - self.dnsCheckBox.toggled.connect(self.dns_checkbox_toggled) - self.icmpCheckBox.toggled.connect(self.icmp_checkbox_toggled) ####### devices tab self.dev_list = MultiSelectWidget(self) @@ -141,15 +138,26 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): def __save_changes__(self, thread_monitor): + self.qvm_collection.lock_db_for_writing() + self.anything_changed = False + + ret = self.__apply_basic_tab__() + + if len(ret) > 0 : + thread_monitor.set_error_msg('\n'.join(ret)) + + if self.anything_changed == True: + self.qvm_collection.save() + self.qvm_collection.unlock_db() + if self.tabWidget.isTabEnabled(self.tabs_indices["firewall"]): - self.fw_model.apply_rules() + self.fw_model.apply_rules(self.policyAllowRadioButton.isChecked(), self.dnsCheckBox.isChecked(), self.icmpCheckBox.isChecked()) + if self.tabWidget.isTabEnabled(self.tabs_indices["applications"]): self.AppListManager.save_appmenu_select_changes() - ret = self.__apply_basic_tab__() - if len(ret) > 0 : - thread_monitor.set_error_msg('\n'.join(ret)) thread_monitor.set_finished() + def current_tab_changed(self, idx): @@ -249,72 +257,57 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): if self.vm.name != vmname: if self.vm.is_running(): msg.append("Can't change name of a running VM.") - elif self.qvm_collection.get_vm_by_name(vmname) is not None: - msg.append("A VM named {0} already exists in the system!".format(vmname)) + msg.append("Can't change VM name - a VM named {0} already exists in the system!".format(vmname)) else: oldname = self.vm.name try: - self.qvm_collection.lock_db_for_writing() self.vm.pre_rename(vmname) self.vm.set_name(vmname) self.vm.post_rename(oldname) - self.qvm_collection.save() + self.anything_changed = True except Exception as ex: msg.append(str(ex)) - finally: - self.qvm_collection.unlock_db() - + #vm label changed if self.vmlabel.currentIndex() != self.label_idx: - if self.vm.is_running(): - msg.append("Can't change label of a running VM.") - - else: - label = self.label_list[self.vmlabel.currentIndex()] - self.qvm_collection.lock_db_for_writing() - self.vm.label = label - self.qvm_collection.save() - self.qvm_collection.unlock_db() + label = self.label_list[self.vmlabel.currentIndex()] + self.vm.label = label + self.anything_changed = True #vm template changed if self.template_name.currentIndex() != self.template_idx: new_template_name = self.template_name.currentText() new_template_name = new_template_name.split(' ')[0] - template_vm = self.qvm_collection.get_vm_by_name(new_template_name) assert (template_vm is not None and template_vm.qid in self.qvm_collection) assert template_vm.is_template() - - self.qvm_collection.lock_db_for_writing() self.vm.template = template_vm - self.qvm_collection.save() - self.qvm_collection.unlock_db() - + self.anything_changed = True #vm netvm changed if self.netVM.currentIndex() != self.netvm_idx: new_netvm_name = self.netVM.currentText() new_netvm_name = new_netvm_name.split(' ')[0] - - cmd = ["qvm-prefs", "-s", self.vm.name, "netvm", new_netvm_name] - res = subprocess.check_call(cmd, stderr=subprocess.PIPE) - - if res != 0: - msg.append("Error while setting netVM!") + netvm = self.qvm_collection.get_vm_by_name(new_netvm_name) + assert (netvm is not None and netvm.qid in self.qvm_collection) + assert netvm.is_netvm() + self.vm.uses_default_netvm = (self.vm is self.qvm_collection.get_default_netvm()) + self.vm.netvm = netvm + self.anything_changed = True #include in backups - self.vm.include_in_backups = self.include_in_backups.isChecked() + if self.vm.include_in_backups != self.include_in_backups.isChecked(): + self.vm.include_in_backups = self.include_in_backups.isChecked() #max priv size priv_size = self.priv_size.value() - self.vm.memory = priv_size + if self.vm.memory != priv_size: + self.vm.memory = priv_size + self.anything_changed = True return msg - # template_vm = template_vm_list[dialog.template_name.currentIndex()] - # allow_networking = dialog.allow_networking.isChecked() - ######### firewall tab related def set_fw_model(self, model): @@ -329,16 +322,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): def set_allow(self, allow): self.policyAllowRadioButton.setChecked(allow) self.policyDenyRadioButton.setChecked(not allow) - - def policy_radio_toggled(self, on): - self.fw_model.allow = self.policyAllowRadioButton.isChecked() - - def dns_checkbox_toggled(self, on): - self.fw_model.allowDns = on - - def icmp_checkbox_toggled(self, on): - self.fw_model.allowIcmp = on - + def new_rule_button_pressed(self): dialog = NewFwRuleDlg() self.run_rule_dialog(dialog) @@ -370,6 +354,7 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): def delete_rule_button_pressed(self): for i in set([index.row() for index in self.rulesTreeView.selectedIndexes()]): self.fw_model.removeChild(i) + self.fw_model.fw_changed = True def run_rule_dialog(self, dialog, row = None): if dialog.exec_(): @@ -415,8 +400,10 @@ class VMSettingsWindow(Ui_SettingsDialog, QDialog): item = QubesFirewallRuleItem(address, netmask, port, port2, protocol) if row is not None: self.fw_model.setChild(row, item) + self.fw_model.fw_changed = True else: self.fw_model.appendChild(item) + self.fw_model.fw_changed = True else: QMessageBox.warning(None, "Invalid service name", "Service '{0} is unknown.".format(service))