[node-patches] Change in ovirt-node[master]: tui: Implement engine page

fabiand at fedoraproject.org fabiand at fedoraproject.org
Mon Dec 17 19:18:32 UTC 2012


Fabian Deutsch has uploaded a new change for review.

Change subject: tui: Implement engine page
......................................................................

tui: Implement engine page

This patch adds a basic engine page which can be used as a starting
point for the vdsm plugin.

Change-Id: Icb61deb3d18c824edaa5368f0bd3cb9bd448cfc1
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/bin/ovirt-config-setup
M scripts/tui/src/ovirt/node/config/defaults.py
M scripts/tui/src/ovirt/node/config/network.py
M scripts/tui/src/ovirt/node/setup/engine_page.py
M scripts/tui/src/ovirt/node/setup/network_page.py
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/utils/__init__.py
M scripts/tui/src/ovirt/node/utils/fs.py
M scripts/tui/src/ovirt/node/utils/network.py
M scripts/tui/src/ovirt/node/utils/process.py
10 files changed, 154 insertions(+), 38 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/74/10174/1

diff --git a/scripts/tui/bin/ovirt-config-setup b/scripts/tui/bin/ovirt-config-setup
index 92f70cf..35f481b 100755
--- a/scripts/tui/bin/ovirt-config-setup
+++ b/scripts/tui/bin/ovirt-config-setup
@@ -7,4 +7,4 @@
 #export PYTHONVERBOSE=x
 python -t -m ovirt.node.setup "$@"
 
-reset
\ No newline at end of file
+#reset
diff --git a/scripts/tui/src/ovirt/node/config/defaults.py b/scripts/tui/src/ovirt/node/config/defaults.py
index 1cc88fd..eb9e3a2 100644
--- a/scripts/tui/src/ovirt/node/config/defaults.py
+++ b/scripts/tui/src/ovirt/node/config/defaults.py
@@ -103,13 +103,30 @@
         for key, value in cfg.items():
             if remove_empty and value is None:
                 del cfg[key]
-            assert type(value) in [str, unicode] or value is None
+            if value is not None and type(value) not in [str, unicode]:
+                raise TypeError("The type (%s) of %s is not allowed" %
+                                (type(value), key))
         self._write(cfg)
 
     def get_dict(self):
-        cfg = {}
         with open(self.filename) as source:
-            for line in source:
+            cfg = self._parse_dict(source)
+        return cfg
+
+    def _parse_dict(self, source):
+        """Parse a simple shell-var-style lines into a dict:
+
+        >>> import StringIO
+        >>> txt = "# A comment\\n"
+        >>> txt += "A=ah\\n"
+        >>> txt += "B=beh\\n"
+        >>> txt += "C=\\"ceh\\"\\n"
+        >>> p = SimpleProvider("/tmp/cfg_dummy")
+        >>> sorted(p._parse_dict(StringIO.StringIO(txt)).items())
+        [('A', 'ah'), ('B', 'beh'), ('C', 'ceh')]
+        """
+        cfg = {}
+        for line in source:
                 if line.startswith("#"):
                     continue
                 key, value = line.split("=", 1)
diff --git a/scripts/tui/src/ovirt/node/config/network.py b/scripts/tui/src/ovirt/node/config/network.py
index 7a93604..d191794 100644
--- a/scripts/tui/src/ovirt/node/config/network.py
+++ b/scripts/tui/src/ovirt/node/config/network.py
@@ -121,18 +121,28 @@
 
 
 def timeservers(new_servers=None):
-    """Get or set TIME servers
+    """Get or set timeservers in the config files
     """
     augpath = "/files/etc/ntp.conf/server"
     return _aug_get_or_set(augpath, new_servers)
 
 
 def hostname(new_hostname=None):
-    """Get or set the current hostname
+    """Get or set the current hostname in the config files
     """
     aug = utils.AugeasWrapper()
     augpath = "/files/etc/sysconfig/network/HOSTNAME"
+    sys_hostname = None
     if new_hostname:
         aug.set(augpath, new_hostname)
-        utils.process.system("hostname %s" % new_hostname)
-    return aug.get(augpath)
+        sys_hostname = utils.network.hostname(new_hostname)
+    cfg_hostname = aug.get(augpath)
+
+    if sys_hostname and (sys_hostname != cfg_hostname):
+        # A trivial check: Check that the configured hostname equals the
+        # configured one (only check if we are configuring a new hostname)
+        raise RuntimeError(("A new hostname was configured (%s) but the " +
+                            "systems hostname (%s) wasn't set accordingly.") %
+                            (cfg_hostname, sys_hostname))
+
+    return cfg_hostname
diff --git a/scripts/tui/src/ovirt/node/setup/engine_page.py b/scripts/tui/src/ovirt/node/setup/engine_page.py
index 2f461b9..c13694d 100644
--- a/scripts/tui/src/ovirt/node/setup/engine_page.py
+++ b/scripts/tui/src/ovirt/node/setup/engine_page.py
@@ -18,16 +18,15 @@
 # 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
+from ovirt.node.config.defaults import NodeConfigFileSection
 
 """
 Configure Engine
 """
 
-from ovirt.node import plugins, valid, ui, utils, exceptions
-
 
 class Plugin(plugins.NodePlugin):
-    _model = None
     _widgets = None
 
     def name(self):
@@ -37,15 +36,14 @@
         return 100
 
     def model(self):
-        if not self._model:
-            self._model = {
-                "vdsm.address": "",
-                "vdsm.port": "7634",
-                "vdsm.connect_and_validate": utils.parse_bool(True),
-                "vdsm.password": "",
-                "vdsm.password_confirmation": "",
-            }
-        return self._model
+        model = {
+            "vdsm.address": "",
+            "vdsm.port": "7634",
+            "vdsm.connect_and_validate": False,
+            "vdsm.password": "",
+            "vdsm.password_confirmation": "",
+        }
+        return model
 
     def validators(self):
         return {
@@ -83,16 +81,91 @@
         return page
 
     def on_change(self, changes):
-        self._model.update(changes)
-
-        if self._model["vdsm.password"] != \
-           self._model["vdsm.password_confirmation"]:
-            raise exceptions.InvalidData("Passwords do not match.")
+        pass
 
     def on_merge(self, effective_changes):
-        pass
+        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)
 
         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)
+            self.logger.debug("Setting VDSM server and port (%s)" % values)
+
+            # Use the VDSM class below to build a transaction
+            model = VDSM()
+            model.update(*values)
+            txs += model.transaction()
+
+        if changes.any_key_in_change(["vdsm.connect_and_validate"]):
+            self.logger.debug("Connecting to engine")
+
+            class ActivateVDSM(utils.Transaction.Element):
+                title = "Activating VDSM"
+
+                def __init__(self):
+                    super(ActivateVDSM, self).__init__()
+                    self.vdsm = VDSM()
+
+                def prepare(self):
+                    """Ping the management server before we try to activate
+                    the connection to it
+                    """
+                    cfg = dict(self.vdsm.retrieve())
+                    server, port = (cfg["server"], cfg["port"])
+                    retval = utils.process.system("ping -c 1 '%s'" % server)
+                    self.logger.debug("Pinged server with %s" % retval)
+                    if retval != 0:
+                        raise RuntimeError("Unable to reach given server: %s" %
+                                           server)
+
+                def commit(self):
+                    self.logger.info("Connecting to VDSM server")
+
+            txs += [ActivateVDSM()]
+
         progress_dialog = ui.TransactionProgressDialog(txs, self)
         progress_dialog.run()
+
+
+class VDSM(NodeConfigFileSection):
+    """Class to handle VDSM configuration
+
+    >>> from ovirt.node.config.defaults import ConfigFile, SimpleProvider
+    >>> fn = "/tmp/cfg_dummy"
+    >>> cfgfile = ConfigFile(fn, SimpleProvider)
+    >>> n = VDSM(cfgfile)
+    >>> n.update("engine.example.com", "1234")
+    >>> sorted(n.retrieve().items())
+    [('port', '1234'), ('server', 'engine.example.com')]
+    """
+    keys = ("OVIRT_MANAGEMENT_SERVER",
+            "OVIRT_MANAGEMENT_PORT")
+
+    @NodeConfigFileSection.map_and_update_defaults_decorator
+    def update(self, server, port):
+        (valid.Empty() | valid.FQDNOrIPAddress())(server)
+        (valid.Empty() | valid.Port())(port)
+
+    def transaction(self):
+        cfg = dict(self.retrieve())
+        server, port = (cfg["server"], cfg["port"])
+
+        class ConfigureVDSM(utils.Transaction.Element):
+            title = "Setting VDSM server and port"
+
+            def commit(self):
+                self.logger.info("Setting: %s:%s" % (server, port))
+
+        tx = utils.Transaction("Configuring VDSM")
+        tx.append(ConfigureVDSM())
+
+        return tx
diff --git a/scripts/tui/src/ovirt/node/setup/network_page.py b/scripts/tui/src/ovirt/node/setup/network_page.py
index e592bc3..dafda0e 100644
--- a/scripts/tui/src/ovirt/node/setup/network_page.py
+++ b/scripts/tui/src/ovirt/node/setup/network_page.py
@@ -24,10 +24,10 @@
 
 from ovirt.node import plugins, ui, valid, utils
 from ovirt.node.config import defaults
-import ovirt.node.utils.network
+from ovirt.node.utils import network
 
 
-class Plugin(ovirt.node.plugins.NodePlugin):
+class Plugin(plugins.NodePlugin):
     """This is the network page
     """
 
@@ -62,7 +62,7 @@
         }
 
         model["hostname"] = defaults.Hostname().retrieve()["hostname"] or \
-                            utils.system.Hostname().hostname()
+                            network.hostname()
 
         # Pull name-/timeservers from config files (not defaults)
         nameservers = defaults.Nameservers().retrieve()["servers"]
@@ -128,7 +128,7 @@
         justify = lambda txt, l: txt.ljust(l)[0:l]
         node_nics = []
         first_nic = None
-        for name, nic in sorted(ovirt.node.utils.network.node_nics().items()):
+        for name, nic in sorted(utils.network.node_nics().items()):
             if first_nic == None:
                 first_nic = name
             bootproto = "Configured" if nic["bootproto"] else "Unconfigured"
@@ -151,7 +151,7 @@
         self.logger.debug("Building NIC details dialog for %s" % iface)
 
         self.logger.debug("Getting informations for NIC details page")
-        live = ovirt.node.utils.network.node_nics()[iface]
+        live = utils.network.node_nics()[iface]
         cfg = defaults.Network().retrieve()
 
         self.logger.debug("live: %s" % live)
diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index 5c79fbf..17dd41f 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -385,6 +385,7 @@
         self.plugin.application.ui.show_dialog(self)
         self._close_button.enabled(False)
         if self.transaction:
+            self.logger.debug("Initiating transaction")
             self.__run_transaction()
         else:
             self.add_update("There were no changes, nothing to do.")
@@ -392,6 +393,7 @@
 
     def __run_transaction(self):
         try:
+            self.logger.debug("Preparing transaction %s" % self.transaction)
             self.transaction.prepare()  # Just to display something in dry mode
             for idx, e in enumerate(self.transaction):
                 txt = "(%s/%s) %s" % (idx + 1, len(self.transaction), e.title)
@@ -399,8 +401,8 @@
                 self.plugin.dry_or(lambda: e.commit())
             self.add_update("\nAll changes were applied successfully.")
         except Exception as e:
-            self.add_update("\nAn error occurred when applying the changes:")
-            self.add_update(e.message)
+            self.add_update("\nAn error occurred while applying the changes:")
+            self.add_update("%s" % e.message)
             self.logger.warning("'%s' on transaction '%s': %s - %s" %
                                 (type(e), self.transaction, e, e.message))
             self.logger.debug(str(traceback.format_exc()))
diff --git a/scripts/tui/src/ovirt/node/utils/__init__.py b/scripts/tui/src/ovirt/node/utils/__init__.py
index 90b10c2..6c082bb 100644
--- a/scripts/tui/src/ovirt/node/utils/__init__.py
+++ b/scripts/tui/src/ovirt/node/utils/__init__.py
@@ -217,6 +217,7 @@
         self.extend(elements)
 
     def prepare(self):
+        self._prepared_elements = []
         for element in self:
             self.logger.debug("Preparing element '%s'" % element)
             if Transaction.Element not in element.__class__.mro():
diff --git a/scripts/tui/src/ovirt/node/utils/fs.py b/scripts/tui/src/ovirt/node/utils/fs.py
index 96aa1af..2c024ef 100644
--- a/scripts/tui/src/ovirt/node/utils/fs.py
+++ b/scripts/tui/src/ovirt/node/utils/fs.py
@@ -52,7 +52,7 @@
         dstf.write(srcf.read())
 
 
-def atomic_write(self, filename, contents):
+def atomic_write(filename, contents):
     backup = BackupedFiles([filename], ".temp")
     backup.create()
     backup_filename = backup.of(filename)
@@ -61,7 +61,7 @@
         dst.write(contents)
 
     fns = (backup_filename, filename)
-    self.logger.debug("Moving '%s' to '%s' atomically" % fns)
+    LOGGER.debug("Moving '%s' to '%s' atomically" % fns)
     try:
         os.rename(*fns)
     except Exception as e:
diff --git a/scripts/tui/src/ovirt/node/utils/network.py b/scripts/tui/src/ovirt/node/utils/network.py
index b765ef0..c4deab8 100644
--- a/scripts/tui/src/ovirt/node/utils/network.py
+++ b/scripts/tui/src/ovirt/node/utils/network.py
@@ -18,7 +18,7 @@
 # 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 base
+from ovirt.node import base, utils
 from socket import inet_ntoa
 from struct import pack
 import glob
@@ -471,3 +471,16 @@
 
     def items(self):
         return (self.address, self.netmask)
+
+
+def hostname(new_hostname=None):
+    """Retrieve/Set the systems hostname
+
+    Args:
+        new_hostname: (Optional) new hostname to be set
+    Returns:
+        The current hostname
+    """
+    if new_hostname:
+        utils.process.system("hostname %s" % new_hostname)
+    return utils.process.pipe("hostname", without_retval=True)
diff --git a/scripts/tui/src/ovirt/node/utils/process.py b/scripts/tui/src/ovirt/node/utils/process.py
index e84714f..3eb9c50 100644
--- a/scripts/tui/src/ovirt/node/utils/process.py
+++ b/scripts/tui/src/ovirt/node/utils/process.py
@@ -57,8 +57,8 @@
 
 
 def pipe(cmd, stdin=None, without_retval=False):
-    """Run a command interactively and cath it's output.
-    This functions allows to pass smoe input to a running command.
+    """Run a command interactively and catch it's output.
+    This functions allows to pass some input to a running command.
 
     >>> r = pipe("echo -n Hi")
     >>> type(r[1])


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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icb61deb3d18c824edaa5368f0bd3cb9bd448cfc1
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