[node-patches] Change in ovirt-node[master]: tui: Rework change handling

fabiand at fedoraproject.org fabiand at fedoraproject.org
Tue Dec 18 11:20:35 UTC 2012


Fabian Deutsch has uploaded a new change for review.

Change subject: tui: Rework change handling
......................................................................

tui: Rework change handling

These changes allow a better access to and handling of changes.
Additionally some validator was introduced to allow a better validation
of UI fields against each other (e.g. Password and Confirm Password).

Change-Id: I4c404299a76ca6037604abd56dffe134cd5a05f9
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/base.py
M scripts/tui/src/ovirt/node/plugins.py
M scripts/tui/src/ovirt/node/setup/engine_page.py
M scripts/tui/src/ovirt/node/setup/kdump_page.py
M scripts/tui/src/ovirt/node/setup/keyboard_page.py
M scripts/tui/src/ovirt/node/setup/logging_page.py
M scripts/tui/src/ovirt/node/setup/monitoring_page.py
M scripts/tui/src/ovirt/node/setup/network_page.py
M scripts/tui/src/ovirt/node/setup/remote_storage_page.py
M scripts/tui/src/ovirt/node/setup/security_page.py
M scripts/tui/src/ovirt/node/setup/snmp_page.py
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/ui/builder.py
13 files changed, 213 insertions(+), 194 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/91/10191/1

diff --git a/scripts/tui/src/ovirt/node/base.py b/scripts/tui/src/ovirt/node/base.py
index 355237b..655dacd 100644
--- a/scripts/tui/src/ovirt/node/base.py
+++ b/scripts/tui/src/ovirt/node/base.py
@@ -80,7 +80,7 @@
         if not self._signal_cbs:
             raise Exception("Signals not initialized %s for %s" % (name, self))
         if name not in self._signal_cbs:
-            raise Exception("Unregistered signal %s for %s" % (name, self))
+            raise Exception("Unregistered signal '%s' for '%s'" % (name, self))
         self._signal_cbs[name].append(cb)
 
     def emit_signal(self, name, userdata=None):
diff --git a/scripts/tui/src/ovirt/node/plugins.py b/scripts/tui/src/ovirt/node/plugins.py
index 0b98091..e71b9b1 100644
--- a/scripts/tui/src/ovirt/node/plugins.py
+++ b/scripts/tui/src/ovirt/node/plugins.py
@@ -22,8 +22,7 @@
 """
 This contains much stuff related to plugins
 """
-from ovirt.node import base, exceptions
-import ovirt.node.exceptions
+from ovirt.node import base, exceptions, valid
 import pkgutil
 
 
@@ -71,7 +70,7 @@
     def __init__(self, application):
         super(NodePlugin, self).__init__()
         self.__changes = {}
-        self.__invalid_changes = {}
+        self.__invalid_changes = Changeset()
         self.application = application
         self.sig_valid = self.register_signal("valid")
 
@@ -122,16 +121,30 @@
         Raises:
             InvalidData on any invalid data
         """
+        validators = self.validators()
         for path, value in changes.items():
-            if path in self.validators():
+            if path in validators:
                 msg = None
                 try:
-                    msg = self.validators()[path](value)
-                except ovirt.node.exceptions.InvalidData as e:
+                    msg = validators[path](value)
+                except exceptions.InvalidData as e:
                     msg = e.message
+
                 # True and None are allowed values
-                if msg not in [True, None]:
-                    raise ovirt.node.exceptions.InvalidData(msg)
+                if msg in [True, None]:
+                    self.__invalid_changes.drop([path])
+                else:
+                    self.logger.debug("Failed to validate " +
+                                      "'%s' with '%s'" % (path, value))
+                    self.__invalid_changes.update({path: value})
+                    raise exceptions.InvalidData(msg)
+
+        # Is valid if no invalid_changes
+        is_valid = self.__invalid_changes.is_empty()
+        self.logger.debug("Valid yet? %s (%s)" % (is_valid,
+                                                  self.__invalid_changes))
+        self.sig_valid.emit(is_valid)
+
         return True
 
     def ui_name(self):
@@ -193,7 +206,7 @@
             self.on_change(model)
         except NotImplementedError:
             self.logger.debug("Plugin has no model")
-        except ovirt.node.exceptions.InvalidData:
+        except exceptions.InvalidData:
             self.logger.warning("Plugins model does not pass semantic " +
                                 "check: %s" % model)
             is_valid = False
@@ -228,15 +241,11 @@
                 self.validate(change)
             self.on_change(change)
         except exceptions.InvalidData as e:
-            self.__invalid_changes.update(change)
             self.sig_valid.emit(False)
             raise e
         self.__changes.update(change)
         self.logger.debug("Sum of all UI changes up to now: %s" % \
                           self.__changes)
-        self.__invalid_changes = {k: v
-                                  for k, v in self.__invalid_changes.items()
-                                  if k not in change}
         self.sig_valid.emit(True)
         return True
 
@@ -299,7 +308,7 @@
                                              else self.__changes
         if include_invalid:
             changes.update(self.__invalid_changes)
-        return changes
+        return Changeset(changes)
 
     def is_valid_changes(self):
         """If all changes are valid or not
@@ -307,7 +316,7 @@
             If there are no invalid changes - so all changes valid
         """
         self.logger.debug("Invalid changes: %s" % self.__invalid_changes)
-        return len(self.__invalid_changes) == 0
+        return self.__invalid_changes.is_empty()
 
     def __effective_changes(self):
         """Calculates the effective changes, so changes which change the
@@ -333,57 +342,72 @@
         return effective_changes
 
     def dry_or(self, func):
+        """Do nothing (when we are running dry) or run func
+        """
         if self.application.args.dry:
             self.logger.info("Running dry, otherwise: %s" % func)
         else:
             self.logger.info("Running %s" % func)
-            func()
+            return func()
 
 
-class ChangesHelper(base.Base):
-    def __init__(self, changes):
-        self.changes = changes
+class Changeset(dict, base.Base):
+    """A wrapper around a dict to provide some convenience functions
+    """
+    def __init__(self, changes=None):
+        super(Changeset, self).__init__()
+        base.Base.__init__(self)
+        if changes:
+            self.update(changes)
 
-    def if_keys_exist_run(self, keys, func):
-        """Run func if all keys are present in the changes.
-        The values of the change entries for each key in keys are passed as
-        arguments to the function func
+    def values_for(self, keys):
+        assert self.contains_all(keys), "Missing keys: %s" % ( \
+                                set(keys).difference(set(self.keys())))
+        return [self[key] for key in keys]
 
-        >>> changes = {
-        ... "foo": 1,
-        ... "bar": 2,
-        ... "baz": 0
-        ... }
-        >>> helper = ChangesHelper(changes)
-        >>> cb = lambda foo, bar: foo + bar
-        >>> helper.if_keys_exist_run(["foo", "bar"], cb)
-        3
-        >>> helper.if_keys_exist_run(["foo", "baz"], cb)
-        1
-        >>> helper.if_keys_exist_run(["win", "dow"], cb)
+    def contains_all(self, keys):
+        return set(keys).issubset(set(self.keys()))
 
-        Args:
-            keys: A list of keys which need to be present in the changes
-            func: The function to be run, values of keys are passed as args
-        """
-        if self.all_keys_in_change(keys):
-            return func(*[self.changes[key] for key in keys])
-
-    def get_key_values(self, keys):
-        assert self.all_keys_in_change(keys), "Missing keys: %s" % ( \
-                                set(keys).difference(set(self.changes.keys())))
-        return [self.changes[key] for key in keys]
-
-    def all_keys_in_change(self, keys):
-        return set(keys).issubset(set(self.changes.keys()))
-
-    def any_key_in_change(self, keys):
-        return any([key in self.changes for key in keys])
+    def contains_any(self, keys):
+        return any([key in self for key in keys])
 
     def __getitem__(self, key):
-        if key in self.changes:
-            return self.changes[key]
+        if key in self:
+            return dict.__getitem__(self, key)
         return None
+
+    def reset(self, changes):
+        self.clear()
+        self.update(changes)
+
+    def drop(self, keys):
+        for key in keys:
+            del self[key]
+
+    def __setitem__(self, key, value):
+        dict.__setitem__(self, key, value)
+
+    def __delitem__(self, key):
+        if key in self:
+            dict.__delitem__(self, key)
+
+    def is_empty(self):
+        """If there are any keys set
+
+        >>> c = Changeset()
+        >>> c.is_empty()
+        True
+        >>> c.update({"a": 1})
+        >>> c.is_empty()
+        False
+        >>> c.drop(["a"])
+        >>> c.is_empty()
+        True
+        """
+        return len(self) == 0
+
+    def update(self, changes):
+        dict.update(self, changes)
 
 
 class WidgetsHelper(dict, base.Base):
@@ -430,3 +454,20 @@
             """Return the UI elements of this group
             """
             return self.widgethelper.subset(self)
+
+
+class Validator:
+    class SameAsIn(valid.Validator):
+        """Validator to validate a value against the value from other paths
+        """
+        def __init__(self, plugin, other_path, other_name):
+            self._plugin = plugin
+            self._paths = [other_path]
+            self.description = "the same value as field '%s'" % other_name
+            super(Validator.SameAsIn, self).__init__()
+
+        def validate(self, value):
+            all_changes = {p: None for p in self._paths}
+            all_changes.update(self._plugin.pending_changes(False, True))
+            return all((v == value for path, v in all_changes.items()
+                        if path in self._paths))
diff --git a/scripts/tui/src/ovirt/node/setup/engine_page.py b/scripts/tui/src/ovirt/node/setup/engine_page.py
index 4522498..3537ca7 100644
--- a/scripts/tui/src/ovirt/node/setup/engine_page.py
+++ b/scripts/tui/src/ovirt/node/setup/engine_page.py
@@ -18,9 +18,9 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.  A copy of the GNU General Public License is
 # also available at http://www.gnu.org/copyleft/gpl.html.
-from ovirt.node import plugins, valid, ui, utils, exceptions
+from ovirt.node import plugins, valid, ui, utils
 from ovirt.node.config.defaults import NodeConfigFileSection
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 """
 Configure Engine
@@ -88,19 +88,18 @@
 
     def on_merge(self, effective_changes):
         self.logger.info("Saving engine stuff")
-        changes = plugins.ChangesHelper(self.pending_changes(False))
-        m = dict(self.model())
-        m.update(effective_changes)
-        effective_model = plugins.ChangesHelper(m)
-        self.logger.info("Effective model %s" % effective_model)
-        self.logger.info("Effective changes %s" % effective_changes)
-        self.logger.info("All changes %s" % changes)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
+
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         txs = utils.Transaction("Configuring oVirt Engine")
 
         vdsm_keys = ["vdsm.address", "vdsm.port"]
-        if changes.any_key_in_change(vdsm_keys):
-            values = effective_model.get_key_values(vdsm_keys)
+        if changes.contains_any(vdsm_keys):
+            values = effective_model.values_for(vdsm_keys)
             self.logger.debug("Setting VDSM server and port (%s)" % values)
 
             # Use the VDSM class below to build a transaction
@@ -108,11 +107,11 @@
             model.update(*values)
             txs += model.transaction()
 
-        if changes.any_key_in_change(["vdsm.password_confirmation"]):
+        if changes.contains_any(["vdsm.password_confirmation"]):
             self.logger.debug("Setting engine password")
             txs += [SetEnginePassword()]
 
-        if changes.any_key_in_change(["vdsm.connect_and_validate"]):
+        if changes.contains_any(["vdsm.connect_and_validate"]):
             self.logger.debug("Connecting to engine")
             txs += [ActivateVDSM()]
 
@@ -170,7 +169,7 @@
         the connection to it
         """
         cfg = dict(self.vdsm.retrieve())
-        server, port = (cfg["server"], cfg["port"])
+        server = cfg["server"]
         retval = utils.process.system("ping -c 1 '%s'" % server)
         self.logger.debug("Pinged server with %s" % retval)
         if retval != 0:
@@ -185,4 +184,4 @@
     title = "Setting Engine password"
 
     def commit(self):
-        self.logger.info("Setting Engine password")
\ No newline at end of file
+        self.logger.info("Setting Engine password")
diff --git a/scripts/tui/src/ovirt/node/setup/kdump_page.py b/scripts/tui/src/ovirt/node/setup/kdump_page.py
index be6cff7..83d99fd 100644
--- a/scripts/tui/src/ovirt/node/setup/kdump_page.py
+++ b/scripts/tui/src/ovirt/node/setup/kdump_page.py
@@ -24,7 +24,7 @@
 
 from ovirt.node import utils, plugins, ui, valid
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 
 class Plugin(plugins.NodePlugin):
@@ -116,21 +116,20 @@
         case it is called by on_change
         """
         self.logger.debug("Saving kdump page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving kdump page: %s" % changes.changes)
-        self.logger.debug("Kdump page model: %s" % effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         kdump_keys = ["kdump.type", "kdump.ssh_location", "kdump.nfs_location"]
 
         txs = utils.Transaction("Updating kdump related configuration")
 
-        if changes.any_key_in_change(kdump_keys):
+        if changes.contains_any(kdump_keys):
             model = defaults.KDump()
-            ktype, sshloc, nfsloc = effective_model.get_key_values(kdump_keys)
+            ktype, sshloc, nfsloc = effective_model.values_for(kdump_keys)
             if ktype == "nfs":
                 model.update(nfsloc, None, None)
             elif ktype == "ssh":
diff --git a/scripts/tui/src/ovirt/node/setup/keyboard_page.py b/scripts/tui/src/ovirt/node/setup/keyboard_page.py
index 5ae835c..aacd924 100644
--- a/scripts/tui/src/ovirt/node/setup/keyboard_page.py
+++ b/scripts/tui/src/ovirt/node/setup/keyboard_page.py
@@ -24,7 +24,7 @@
 
 from ovirt.node import plugins, ui, utils
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 
 class Plugin(plugins.NodePlugin):
@@ -69,21 +69,20 @@
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving keyboard page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving keyboard page: %s" % changes.changes)
-        self.logger.debug("Keyboard page model: %s" % effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         layout_keys = ["keyboard.layout"]
 
         txs = utils.Transaction("Updating keyboard related configuration")
 
-        if changes.any_key_in_change(layout_keys):
+        if changes.contains_any(layout_keys):
             model = defaults.Keyboard()
-            model.update(*effective_model.get_key_values(layout_keys))
+            model.update(*effective_model.values_for(layout_keys))
             txs += model.transaction()
 
         progress_dialog = ui.TransactionProgressDialog(txs, self)
diff --git a/scripts/tui/src/ovirt/node/setup/logging_page.py b/scripts/tui/src/ovirt/node/setup/logging_page.py
index 74e8f8f..fac9be3 100644
--- a/scripts/tui/src/ovirt/node/setup/logging_page.py
+++ b/scripts/tui/src/ovirt/node/setup/logging_page.py
@@ -24,7 +24,7 @@
 
 from ovirt.node import plugins, valid, ui, utils
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 
 class Plugin(plugins.NodePlugin):
@@ -96,35 +96,34 @@
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving logging page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving logging page: %s" % changes.changes)
-        self.logger.debug("Logging page model: %s" % effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         txs = utils.Transaction("Updating logging related configuration")
 
         # If any logrotate key changed ...
         logrotate_keys = ["logrotate.max_size"]
-        if changes.any_key_in_change(logrotate_keys):
+        if changes.contains_any(logrotate_keys):
             # Get all logrotate values fomr the effective model
             model = defaults.Logrotate()
             # And update the defaults
-            model.update(*effective_model.get_key_values(logrotate_keys))
+            model.update(*effective_model.values_for(logrotate_keys))
             txs += model.transaction()
 
         rsyslog_keys = ["rsyslog.address", "rsyslog.port"]
-        if changes.any_key_in_change(rsyslog_keys):
+        if changes.contains_any(rsyslog_keys):
             model = defaults.Syslog()
-            model.update(*effective_model.get_key_values(rsyslog_keys))
+            model.update(*effective_model.values_for(rsyslog_keys))
             txs += model.transaction()
 
         netconsole_keys = ["netconsole.address", "netconsole.port"]
-        if changes.any_key_in_change(netconsole_keys):
+        if changes.contains_any(netconsole_keys):
             model = defaults.Netconsole()
-            model.update(*effective_model.get_key_values(netconsole_keys))
+            model.update(*effective_model.values_for(netconsole_keys))
             txs += model.transaction()
 
         progress_dialog = ui.TransactionProgressDialog(txs, self)
diff --git a/scripts/tui/src/ovirt/node/setup/monitoring_page.py b/scripts/tui/src/ovirt/node/setup/monitoring_page.py
index 4967517..d4e2a0b 100644
--- a/scripts/tui/src/ovirt/node/setup/monitoring_page.py
+++ b/scripts/tui/src/ovirt/node/setup/monitoring_page.py
@@ -20,7 +20,7 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 from ovirt.node import plugins, ui, valid, utils
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 """
 Configure Monitoring
@@ -74,21 +74,20 @@
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving monitoring page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving monitoring page: %s" % changes.changes)
-        self.logger.debug("monitoring model: %s" % effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         collectd_keys = ["collectd.address", "collectd.port"]
 
         txs = utils.Transaction("Updating monitoring configuration")
 
-        if changes.any_key_in_change(collectd_keys):
+        if changes.contains_any(collectd_keys):
             model = defaults.Collectd()
-            model.update(*effective_model.get_key_values(collectd_keys))
+            model.update(*effective_model.values_for(collectd_keys))
             txs += model.transaction()
 
         progress_dialog = ui.TransactionProgressDialog(txs, self)
diff --git a/scripts/tui/src/ovirt/node/setup/network_page.py b/scripts/tui/src/ovirt/node/setup/network_page.py
index dafda0e..480c545 100644
--- a/scripts/tui/src/ovirt/node/setup/network_page.py
+++ b/scripts/tui/src/ovirt/node/setup/network_page.py
@@ -18,13 +18,13 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 # MA  02110-1301, USA.  A copy of the GNU General Public License is
 # also available at http://www.gnu.org/copyleft/gpl.html.
+from ovirt.node import plugins, ui, valid, utils
+from ovirt.node.config import defaults
+from ovirt.node.plugins import Changeset
+from ovirt.node.utils import network
 """
 Network page plugin
 """
-
-from ovirt.node import plugins, ui, valid, utils
-from ovirt.node.config import defaults
-from ovirt.node.utils import network
 
 
 class Plugin(plugins.NodePlugin):
@@ -249,7 +249,7 @@
 
     def on_change(self, changes):
         self.logger.info("Checking network stuff")
-        helper = plugins.ChangesHelper(changes)
+        helper = plugins.Changeset(changes)
         bootproto = helper["dialog.nic.ipv4.bootproto"]
         if bootproto:
             if bootproto in ["static"]:
@@ -260,12 +260,13 @@
 
     def on_merge(self, effective_changes):
         self.logger.info("Saving network stuff")
-        changes = self.pending_changes(False)
-        effective_model = dict(self.model())
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
         effective_model.update(effective_changes)
-        self.logger.info("Effective model %s" % effective_model)
+
+        self.logger.debug("Changes: %s" % changes)
         self.logger.info("Effective changes %s" % effective_changes)
-        self.logger.info("All changes %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         # Special case: A NIC was selected, display that dialog!
         if "nics" in changes and len(changes) == 1:
@@ -285,13 +286,12 @@
         # This object will contain all transaction elements to be executed
         txs = utils.Transaction("DNS and NTP configuration")
 
-        e_changes_h = plugins.ChangesHelper(effective_changes)
-        e_model_h = plugins.ChangesHelper(effective_model)
+        e_changes_h = plugins.Changeset(effective_changes)
 
         nameservers = []
         dns_keys = ["dns[0]", "dns[1]"]
-        if e_changes_h.any_key_in_change(dns_keys):
-            nameservers += e_model_h.get_key_values(dns_keys)
+        if e_changes_h.contains_any(dns_keys):
+            nameservers += effective_model.values_for(dns_keys)
         if nameservers:
             self.logger.info("Setting new nameservers: %s" % nameservers)
             model = defaults.Nameservers()
@@ -300,8 +300,8 @@
 
         timeservers = []
         ntp_keys = ["ntp[0]", "ntp[1]"]
-        if e_changes_h.any_key_in_change(ntp_keys):
-            timeservers += e_model_h.get_key_values(ntp_keys)
+        if e_changes_h.contains_any(ntp_keys):
+            timeservers += effective_model.values_for(ntp_keys)
         if timeservers:
             self.logger.info("Setting new timeservers: %s" % timeservers)
             model = defaults.Timeservers()
@@ -309,19 +309,18 @@
             txs += model.transaction()
 
         hostname_keys = ["hostname"]
-        if e_changes_h.any_key_in_change(hostname_keys):
-            value = e_model_h.get_key_values(hostname_keys)
+        if e_changes_h.contains_any(hostname_keys):
+            value = effective_model.values_for(hostname_keys)
             self.logger.info("Setting new hostname: %s" % value)
             model = defaults.Hostname()
             model.update(*value)
             txs += model.transaction()
 
         # For the NIC details dialog:
-        if e_changes_h.any_key_in_change(self._nic_details_group):
+        if e_changes_h.contains_any(self._nic_details_group):
             # If any networking related key was changed, reconfigure networking
-            helper = plugins.ChangesHelper(effective_model)
             # Fetch the values for the nic keys, they are used as arguments
-            args = helper.get_key_values(self._nic_details_group)
+            args = effective_model.values_for(self._nic_details_group)
             txs += self._configure_nic(*args)
 
         progress_dialog = ui.TransactionProgressDialog(txs, self)
diff --git a/scripts/tui/src/ovirt/node/setup/remote_storage_page.py b/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
index ad2cbd9..9d8179d 100644
--- a/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
+++ b/scripts/tui/src/ovirt/node/setup/remote_storage_page.py
@@ -20,7 +20,7 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 from ovirt.node import utils, valid, plugins, ui
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 from ovirt.node.utils import storage
 
 """
@@ -77,29 +77,27 @@
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving remote storage page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving remote storage page: %s" % changes.changes)
-        self.logger.debug("Remote storage page model: %s" %
-                          effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         txs = utils.Transaction("Updating remote storage configuration")
 
         iscsi_keys = ["iscsi.initiator_name"]
-        if changes.any_key_in_change(iscsi_keys):
+        if changes.contains_any(iscsi_keys):
             model = defaults.iSCSI()
-            args = effective_model.get_key_values(iscsi_keys)
+            args = effective_model.values_for(iscsi_keys)
             args += [None, None, None]  # No target config
             model.update(*args)
             txs += model.transaction()
 
         nfsv4_keys = ["nfsv4.domain"]
-        if changes.any_key_in_change(nfsv4_keys):
+        if changes.contains_any(nfsv4_keys):
             model = defaults.NFSv4()
-            args = effective_model.get_key_values(nfsv4_keys)
+            args = effective_model.values_for(nfsv4_keys)
             model.update(*args)
             txs += model.transaction()
 
diff --git a/scripts/tui/src/ovirt/node/setup/security_page.py b/scripts/tui/src/ovirt/node/setup/security_page.py
index 96295af..c1626c6 100644
--- a/scripts/tui/src/ovirt/node/setup/security_page.py
+++ b/scripts/tui/src/ovirt/node/setup/security_page.py
@@ -20,7 +20,7 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 from ovirt.node import utils, plugins, ui, valid, exceptions
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 """
 Configure Security
@@ -50,12 +50,16 @@
         return model
 
     def validators(self):
+        same_as_password = plugins.Validator.SameAsIn(self,
+                                                      "passwd.admin.password",
+                                                      "Password")
         number_or_empty = valid.Number(range=[0, None]) | \
                           valid.Empty()
+
         return {
                 "strongrng.num_bytes": number_or_empty,
                 "passwd.admin.password": valid.Text(),
-                "passwd.admin.password_confirmation": valid.Text(),
+                "passwd.admin.password_confirmation": same_as_password,
             }
 
     def ui_content(self):
@@ -79,33 +83,16 @@
         return page
 
     def on_change(self, changes):
-        m = self.model()
-        m.update(self.pending_changes(False, True))
-        m.update(changes)
-        effective_model = ChangesHelper(m)
-
-        passwd_keys = ["passwd.admin.password",
-                       "passwd.admin.password_confirmation"]
-        passwd_widget_group = self._widgets.group(passwd_keys)
-        if effective_model.any_key_in_change(passwd_keys):
-            passwd, passwdc = effective_model.get_key_values(passwd_keys)
-            if passwd == passwdc:
-                # Remove all potential error messages
-                map(lambda e: e.valid(True), passwd_widget_group.elements())
-            else:
-                # Throw an error message
-                raise exceptions.InvalidData("Passwords do not match.")
+        pass
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving security page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving security page: %s" % changes.changes)
-        self.logger.debug("Remote security model: %s" %
-                          effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
         ssh_keys = ["ssh.pwauth", "strongrng.num_bytes",
                     "strongrng.disable_aesni"]
@@ -114,13 +101,13 @@
 
         txs = utils.Transaction("Updating security configuration")
 
-        if changes.any_key_in_change(ssh_keys):
+        if changes.contains_any(ssh_keys):
             model = defaults.SSH()
-            model.update(*effective_model.get_key_values(ssh_keys))
+            model.update(*effective_model.values_for(ssh_keys))
             txs += model.transaction()
 
-        if changes.any_key_in_change(passwd_keys):
-            pw, pwc = effective_model.get_key_values(passwd_keys)
+        if changes.contains_any(passwd_keys):
+            pw, pwc = effective_model.values_for(passwd_keys)
             if pw != pwc:
                 raise exceptions.InvalidData("Passwords do not match")
             passwd = utils.security.Passwd()
diff --git a/scripts/tui/src/ovirt/node/setup/snmp_page.py b/scripts/tui/src/ovirt/node/setup/snmp_page.py
index 3e65e1d..55ec845 100644
--- a/scripts/tui/src/ovirt/node/setup/snmp_page.py
+++ b/scripts/tui/src/ovirt/node/setup/snmp_page.py
@@ -20,7 +20,7 @@
 # also available at http://www.gnu.org/copyleft/gpl.html.
 from ovirt.node import plugins, valid, ui, utils
 from ovirt.node.config import defaults
-from ovirt.node.plugins import ChangesHelper
+from ovirt.node.plugins import Changeset
 
 """
 Configure SNMP
@@ -52,9 +52,12 @@
         return model
 
     def validators(self):
+        same_as_password = plugins.Validator.SameAsIn(self,
+                                                      "snmp.password",
+                                                      "Password")
         return {
-                "passwd.admin.password": valid.Text(),
-                "passwd.admin.password_confirmation": valid.Text(),
+                "snmp.password": valid.Text(),
+                "snmp.password_confirmation": same_as_password,
             }
 
     def ui_content(self):
@@ -75,33 +78,23 @@
         return page
 
     def on_change(self, changes):
-        m = self.model()
-        m.update(self.pending_changes() or {})
-        effective_model = ChangesHelper(m)
-
-        snmp_keys = ["snmp.password",
-                     "snmp.password_confirmation"]
-        if effective_model.any_key_in_change(snmp_keys):
-            passwd, passwdc = effective_model.get_key_values(snmp_keys)
-            #if passwd != passwdc:
-            #    raise exceptions.InvalidData("Passwords do not match.")
+        pass
 
     def on_merge(self, effective_changes):
         self.logger.debug("Saving SNMP page")
-        changes = ChangesHelper(self.pending_changes(False))
-        model = self.model()
-        model.update(effective_changes)
-        effective_model = ChangesHelper(model)
+        changes = Changeset(self.pending_changes(False))
+        effective_model = Changeset(self.model())
+        effective_model.update(effective_changes)
 
-        self.logger.debug("Saving SNMP page: %s" % changes.changes)
-        self.logger.debug("SNMP model: %s" % effective_model.changes)
+        self.logger.debug("Changes: %s" % changes)
+        self.logger.debug("Effective Model: %s" % effective_model)
 
-        snmp_keys = ["snmp.password", "snmp.enabled"]
+        snmp_keys = ["snmp.password_confirmation", "snmp.enabled"]
 
         txs = utils.Transaction("Updating SNMP configuration")
 
-        if changes.any_key_in_change(snmp_keys):
-            values = effective_model.get_key_values(snmp_keys)
+        if changes.contains_any(snmp_keys):
+            values = effective_model.values_for(snmp_keys)
             args = [values[0]]
             if values[1] is False:  # If set to disabled, set password to None
                 args[0] = None
diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index 17dd41f..3e42b17 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -48,13 +48,14 @@
 
 
 class InputElement(Element):
-    """An abstract UI Element pfor user input
+    """An abstract UI Element for user input
     """
 
     def __init__(self, name, is_enabled):
         super(InputElement, self).__init__()
         self.name = name
         self.enabled(is_enabled)
+        self.text("")
 
     @Element.signal_change
     def enabled(self, is_enabled=None):
diff --git a/scripts/tui/src/ovirt/node/ui/builder.py b/scripts/tui/src/ovirt/node/ui/builder.py
index 8a36e2b..0e1724b 100644
--- a/scripts/tui/src/ovirt/node/ui/builder.py
+++ b/scripts/tui/src/ovirt/node/ui/builder.py
@@ -148,6 +148,11 @@
 
     item.connect_signal("valid", on_item_valid_change_cb)
 
+    def on_item_text_change_cb(w, v):
+            widget.set_text(v)
+
+    item.connect_signal("text", on_item_text_change_cb)
+
     def on_widget_value_change(widget, new_value):
         LOGGER.debug("Entry %s changed, calling callback: '%s'" % (widget,
                                                                    path))


--
To view, visit http://gerrit.ovirt.org/10191
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I4c404299a76ca6037604abd56dffe134cd5a05f9
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>



More information about the node-patches mailing list