[Ocfs2-tools-commits] manish commits r806 - trunk/ocfs2console/ocfs2interface

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Apr 14 16:13:35 CDT 2005


Author: manish
Date: 2005-04-14 16:13:32 -0500 (Thu, 14 Apr 2005)
New Revision: 806

Added:
   trunk/ocfs2console/ocfs2interface/o2cb_ctl.py
Modified:
   trunk/ocfs2console/ocfs2interface/Makefile
   trunk/ocfs2console/ocfs2interface/nodeconfig.py
   trunk/ocfs2console/ocfs2interface/pushconfig.py
Log:
Factor out o2cb_ctl utility code into its own module, so pushconfig and
nodeconfig can share it


Modified: trunk/ocfs2console/ocfs2interface/Makefile
===================================================================
--- trunk/ocfs2console/ocfs2interface/Makefile	2005-04-14 21:02:58 UTC (rev 805)
+++ trunk/ocfs2console/ocfs2interface/Makefile	2005-04-14 21:13:32 UTC (rev 806)
@@ -88,6 +88,7 @@
 	mount.py		\
 	menu.py			\
 	nodeconfig.py		\
+	o2cb_ctl.py		\
 	partitionview.py	\
 	process.py		\
 	pushconfig.py		\

Modified: trunk/ocfs2console/ocfs2interface/nodeconfig.py
===================================================================
--- trunk/ocfs2console/ocfs2interface/nodeconfig.py	2005-04-14 21:02:58 UTC (rev 805)
+++ trunk/ocfs2console/ocfs2interface/nodeconfig.py	2005-04-14 21:13:32 UTC (rev 806)
@@ -16,26 +16,21 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
 
 import os
-import types
 
 import gtk
 import gobject
 import pango
 
-from cStringIO import StringIO
- 
 import ocfs2
 import o2cb
 
+import o2cb_ctl
+
 from guiutil import Dialog, set_props, error_box
-from process import Process
 from ipwidget import IPEditor, IPMissing, IPError
 
-CLUSTER_NAME = 'ocfs2'
+DEFAULT_CLUSTER_NAME = 'ocfs2'
 
-O2CB_INIT = '/etc/init.d/o2cb'
-O2CB_CTL = 'o2cb_ctl'
-
 PORT_DEFAULT = 7777
 PORT_MINIMUM = 1000
 PORT_MAXIMUM = 30000
@@ -44,16 +39,24 @@
     COLUMN_NEW_NODE,
     COLUMN_NAME,
     COLUMN_NODE,
-    COLUMN_IP_ADDR,
+    COLUMN_IP_ADDRESS,
     COLUMN_IP_PORT
 ) = range(5)
 
+class Field:
+    def __init__(self, name, column, title, widget_type, field_type):
+        self.name = name
+        self.column = column
+        self.title = title
+        self.widget_type = widget_type
+        self.type = field_type
+
 fields = (
-    (COLUMN_NEW_NODE, 'Active',     None,           bool),
-    (COLUMN_NAME,     'Name',       gtk.Entry,      str),
-    (COLUMN_NODE,     'Node',       None,           int),
-    (COLUMN_IP_ADDR,  'IP Address', IPEditor,       str),
-    (COLUMN_IP_PORT,  'IP Port',    gtk.SpinButton, str)
+    Field('new_node',   COLUMN_NEW_NODE,   'Active',     None,           bool),
+    Field('name',       COLUMN_NAME,       'Name',       gtk.Entry,      str),
+    Field('node',       COLUMN_NODE,       'Node',       None,           int),
+    Field('ip_address', COLUMN_IP_ADDRESS, 'IP Address', IPEditor,       str),
+    Field('ip_port',    COLUMN_IP_PORT,    'IP Port',    gtk.SpinButton, str),
 )
 
 # Hate your ancient distros shipping old pygtks
@@ -63,8 +66,8 @@
     pass
 
 class ClusterConfig(Dialog):
-    def __init__(self, parent=None):
-        self.new_nodes = 0
+    def __init__(self, cluster_name=DEFAULT_CLUSTER_NAME, parent=None):
+        self.cluster_name = cluster_name
 
         Dialog.__init__(self, parent=parent, title='Node Configuration',
                         buttons=(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY,
@@ -123,16 +126,25 @@
         self.sel = self.tv.get_selection()
         self.sel.connect('changed', self.on_select)
 
+        self.load_cluster_state()
+
     def load_cluster_state(self):
-        query_args = '-I -t node -o'
-        o2cb_ctl = O2CBCtl(query_args, 'Querying nodes...', self)
-        success, output, k = o2cb_ctl.reap()
+        try:
+            nodes = o2cb_ctl.get_cluster_nodes(self.cluster_name, self)
+        except o2cb_ctl.CtlError, e:
+            raise ConfError, str(e)
 
-        if not success:
-            raise ConfError, output
+        store = gtk.ListStore(*[typemap.get(f.type, f.type) for f in fields])
 
-        self.store = gtk.ListStore(*[typemap.get(f[3], f[3]) for f in fields])
+        node_data = list((None,) * len(fields))
 
+        for node in nodes:
+            for field in fields:
+                val = node.get(field.name, False)
+                node_data[field.column] = field.type(val)
+
+            store.append(node_data)
+
         def node_compare(store, a, b):
             n1 = store[a][COLUMN_NODE]
             n2 = store[b][COLUMN_NODE]
@@ -144,59 +156,34 @@
             else:
                 return cmp(abs(n1), abs(n2))
               
-        self.store.set_sort_func(COLUMN_NODE, node_compare)
-        self.store.set_sort_column_id(COLUMN_NODE, gtk.SORT_ASCENDING)
+        store.set_sort_func(COLUMN_NODE, node_compare)
+        store.set_sort_column_id(COLUMN_NODE, gtk.SORT_ASCENDING)
 
-        buffer = StringIO(output)
-
-        for line in buffer:
-            if line.startswith('#'):
-                continue
-
-            data = list((None,) * len(fields))
-
-            try:
-                data[COLUMN_NEW_NODE] = False
-
-                (data[COLUMN_NAME],
-                 cluster,
-                 data[COLUMN_NODE],
-                 data[COLUMN_IP_ADDR],
-                 data[COLUMN_IP_PORT],
-                 state) = line.split(':')
-
-                for i in range(0, len(fields)):
-                    data[i] = fields[i][3](data[i])
-            except ValueError:
-                continue
-
-            if cluster == CLUSTER_NAME:
-                self.store.append(data)
-
         self.new_nodes = 0
+        self.store = store
 
-        self.tv.set_model(self.store)
+        self.tv.set_model(store)
 
     def setup_treeview(self):
         self.tv = gtk.TreeView()
         self.tv.set_size_request(350, 200)
 
-        for col, title, widget_type, field_type in fields:
-            if col == COLUMN_NEW_NODE:
-                self.tv.insert_column_with_data_func(-1, title,
+        for field in fields:
+            if field.column == COLUMN_NEW_NODE:
+                self.tv.insert_column_with_data_func(-1, field.title,
                                                      gtk.CellRendererPixbuf(),
                                                      self.active_set_func)
-            elif col == COLUMN_NODE:
-                self.tv.insert_column_with_data_func(-1, title,
+            elif field.column == COLUMN_NODE:
+                self.tv.insert_column_with_data_func(-1, field.title,
                                                      gtk.CellRendererText(),
                                                      self.node_set_func)
             else:
                 cell_renderer = gtk.CellRendererText()
                 cell_renderer.set_property('style', pango.STYLE_ITALIC)
 
-                self.tv.insert_column_with_attributes(-1, title,
+                self.tv.insert_column_with_attributes(-1, field.title,
                                                       cell_renderer,
-                                                      text=col,
+                                                      text=field.column,
                                                       style_set=COLUMN_NEW_NODE)
 
     def active_set_func(self, tree_column, cell, model, iter):
@@ -263,7 +250,7 @@
             return
 
         (attrs[COLUMN_NAME],
-         attrs[COLUMN_IP_ADDR],
+         attrs[COLUMN_IP_ADDRESS],
          attrs[COLUMN_IP_PORT]) = node_attrs
 
     def remove_node(self, b):
@@ -296,7 +283,7 @@
         for row in self.store:
             if row[COLUMN_NEW_NODE]:
                 attrs.append((row[COLUMN_NAME],
-                              row[COLUMN_IP_ADDR],
+                              row[COLUMN_IP_ADDRESS],
                               row[COLUMN_IP_PORT]))
 
         return attrs
@@ -304,16 +291,9 @@
     def apply_changes(self):
         success = False
 
-        for name, ip_addr, ip_port in self.new_node_attrs():
-            add_node_args = ('-C', '-n', name, '-t', 'node',
-                             '-a', 'cluster=%s' % CLUSTER_NAME,
-                             '-a', 'ip_address=%s' % ip_addr,
-                             '-a', 'ip_port=%s' % ip_port,
-                             '-i')
-
-            o2cb_ctl = O2CBCtl(add_node_args, 'Adding node %s...' % name, self)
-            success, output, k = o2cb_ctl.reap()
-
+        for name, ip_address, ip_port in self.new_node_attrs():
+            success, output, k = o2cb_ctl.add_node(name, self.cluster_name,
+                                                   ip_address, ip_port, self)
             if not success:
                 error_box(self, '%s\nCould not add node %s' % (output, name))
                 break
@@ -327,7 +307,7 @@
 
         for row in self.store:
             name = row[COLUMN_NAME]
-            ip_addr = row[COLUMN_IP_ADDR]
+            ip_addr = row[COLUMN_IP_ADDRESS]
 
             existing_names[name] = 1
             existing_ip_addrs[ip_addr] = name
@@ -350,22 +330,22 @@
         widgets = []
         row = 0
 
-        for col, title, widget_type, field_type in fields:
-            if widget_type is None:
+        for field in fields:
+            if field.widget_type is None:
                 widgets.append(None)
                 continue
 
-            label = gtk.Label(title + ':')
+            label = gtk.Label(field.title + ':')
             set_props(label, xalign=1.0)
             table.attach(label, 0, 1, row, row + 1)
 
-            widget = widget_type()
+            widget = field.widget_type()
             table.attach(widget, 1, 2, row, row + 1)
 
-            if col == COLUMN_NAME:
+            if field.column == COLUMN_NAME:
                 #XXX widget.set_max_length(ocfs2.MAX_NODE_NAME_LENGTH)
                 pass
-            elif col == COLUMN_IP_PORT:
+            elif field.column == COLUMN_IP_PORT:
                 widget.set_numeric(True)
 
                 adjustment = gtk.Adjustment(PORT_DEFAULT,
@@ -400,7 +380,7 @@
                 continue
 
             try:
-                ip_addr = widgets[COLUMN_IP_ADDR].get_text()
+                ip_addr = widgets[COLUMN_IP_ADDRESS].get_text()
             except (IPMissing, IPError), msg:
                 error_box(dialog, msg[0])
                 continue
@@ -443,35 +423,16 @@
             else: 
                 break
 
-class O2CBProcess(Process):
-    def __init__(self, args, desc, parent=None):
-        if isinstance(args, types.StringTypes):
-            command = '%s %s' % (self.o2cb_program, args)
-        else:
-            command = (self.o2cb_program,) + tuple(args)
-
-        Process.__init__(self, command, self.o2cb_title, desc, parent)
-
-class O2CBCtl(O2CBProcess):
-    o2cb_program = O2CB_CTL
-    o2cb_title = 'Cluster Control'
-
-class O2CBInit(O2CBProcess):
-    o2cb_program = O2CB_INIT
-    o2cb_title = 'Cluster Stack'
-
 def node_config(parent=None):
     if not os.access(o2cb.FORMAT_CLUSTER_DIR, os.F_OK):
-        load_args = ('load',)
-        o2cb_init = O2CBInit(load_args, 'Starting cluster stack...', parent)
-        success, output, k = o2cb_init.reap()
+        success, output, k = o2cb_ctl.init_load(parent)
 
         if success:
             msg_type = gtk.MESSAGE_INFO
             msg = ('The cluster stack has been started. It needs to be '
                    'running for any clustering functionality to happen. '
                    'Please run "%s enable" to have it started upon bootup.'
-                   % o2cb_init.o2cb_program)
+                   % o2cb_ctl.O2CB_INIT)
         else:
             msg_type = gtk.MESSAGE_WARNING
             msg = ('Could not start cluster stack. This must be resolved '
@@ -489,31 +450,14 @@
         if not success:
             return
 
-#    msg = ('Currently, the clustering software can only handle '
-#           'one cluster at a time. To keep things simple, you '
-#           'are expected to name your cluster "%s". Your '
-#           'configuration file contains a cluster named "%s". '
-#           'Please rename or delete that cluster, and restart '
-#           'the cluster stack before trying to run the cluster '
-#           'configurator again.' % (CLUSTER_NAME, cluster))
+    try:
+        cluster_name = o2cb_ctl.get_active_cluster_name(parent)
+    except o2cb_ctl.CtlError, e:
+        error_box(parent, str(e))
+        return
 
-    query_args = '-I -t cluster -n %s -o' % CLUSTER_NAME
-    o2cb_ctl = O2CBCtl(query_args, 'Querying cluster...', parent)
-    success, output, k = o2cb_ctl.reap()
-
-    if not success:
-        create_args = '-C -n %s -t cluster -i' % CLUSTER_NAME
-        o2cb_ctl = O2CBCtl(query_args, 'Creating cluster...', parent)
-        success, output, k = o2cb_ctl.reap()
-
-        if not success:
-            error_box(parent, '%s\nCould not create cluster' % output)
-            return
-
-    conf = ClusterConfig(parent)
-
     try:
-        conf.load_cluster_state()
+        conf = ClusterConfig(cluster_name, parent)
     except ConfigError, e:
         error_box(parent, '%s: Could not query cluster configuration' % str(e))
         return
@@ -521,10 +465,8 @@
     conf.run()
     conf.destroy()
 
-    if not os.access(o2cb.FORMAT_CLUSTER % CLUSTER_NAME, os.F_OK):
-        online_args = ('online', CLUSTER_NAME),
-        o2cb_init = O2CBInit(online_args, 'Starting OCFS2 cluster...', parent)
-        success, output, k = o2cb_init.reap()
+    if not os.access(o2cb.FORMAT_CLUSTER % cluster_name, os.F_OK):
+        success, output, k = o2cb_ctl.init_online(cluster_name, parent)
 
         if not success:
             msg = ('Could not bring OCFS2 cluster online. This must be '

Added: trunk/ocfs2console/ocfs2interface/o2cb_ctl.py
===================================================================
--- trunk/ocfs2console/ocfs2interface/o2cb_ctl.py	2005-04-14 21:02:58 UTC (rev 805)
+++ trunk/ocfs2console/ocfs2interface/o2cb_ctl.py	2005-04-14 21:13:32 UTC (rev 806)
@@ -0,0 +1,165 @@
+# OCFS2Console - GUI frontend for OCFS2 management and debugging
+# Copyright (C) 2002, 2005 Oracle.  All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 021110-1307, USA.
+
+import types
+
+from cStringIO import StringIO
+
+from process import Process
+from guiutil import error_box
+
+DEFAULT_CLUSTER_NAME = 'ocfs2'
+
+O2CB_INIT = '/etc/init.d/o2cb'
+O2CB_CTL = 'o2cb_ctl'
+
+class CtlError(Exception):
+    pass
+
+class O2CBProcess(Process):
+    def __init__(self, args, desc, parent=None):
+        if isinstance(args, types.StringTypes):
+            command = '%s %s' % (self.o2cb_program, args)
+        else:
+            command = (self.o2cb_program,) + tuple(args)
+
+        Process.__init__(self, command, self.o2cb_title, desc, parent)
+
+class O2CBCtl(O2CBProcess):
+    o2cb_program = O2CB_CTL
+    o2cb_title = 'Cluster Control'
+
+class O2CBInit(O2CBProcess):
+    o2cb_program = O2CB_INIT
+    o2cb_title = 'Cluster Stack'
+
+def init_load(parent=None):
+    args = ('load',)
+    o2cb_init = O2CBInit(args, 'Starting cluster stack...', parent)
+    return o2cb_init.reap()
+
+def init_online(cluster_name, parent=None):
+    desc = 'Starting %s cluster...' % cluster_name
+    args = ('online', cluster_name)
+    o2cb_init = O2CBInit(args, desc, parent)
+    return o2cb_init.reap()
+
+def query_clusters(parent=None):
+    args = '-I -t cluster -o'
+    o2cb_ctl = O2CBCtl(args, 'Querying cluster...', parent)
+    return o2cb_ctl.reap()
+
+def query_nodes(parent=None):
+    args = '-I -t node -o'
+    o2cb_ctl = O2CBCtl(args, 'Querying nodes...', parent)
+    return o2cb_ctl.reap()
+
+def add_node(name, cluster_name, ip_address, ip_port, parent=None):
+    desc = 'Adding node %s...' % name
+    args = ('-C', '-n', name, '-t', 'node',
+            '-a', 'cluster=%s' % cluster_name,
+            '-a', 'ip_address=%s' % ip_address,
+            '-a', 'ip_port=%s' % ip_port,
+            '-i')
+
+    o2cb_ctl = O2CBCtl(args, desc, parent)
+    return o2cb_ctl.reap()
+
+def get_active_cluster_name(parent=None):
+    cluster_name = None
+
+    success, output, k = query_clusters(parent)
+
+    if success:
+        names = []
+
+        buffer = StringIO(output)
+
+        for line in buffer:
+            if line.startswith('#'):
+                continue
+
+            try:
+                name, rest = line.split(':', 1)
+            except ValueError:
+                 continue
+
+            names.append(name)
+
+        if DEFAULT_CLUSTER_NAME in names:
+            cluster_name = DEFAULT_CLUSTER_NAME
+        elif len(names):
+            cluster_name = names[0]
+
+    if cluster_name is None:
+        args = '-C -n %s -t cluster -i' % DEFAULT_CLUSTER_NAME
+        o2cb_ctl = O2CBCtl(args, 'Creating cluster...', parent)
+        success, output, k = o2cb_ctl.reap()
+
+        if success:
+            cluster_name = DEFAULT_CLUSTER_NAME
+        else:
+            errmsg = '%s\nCould not create cluster' % (output,
+                                                       DEFAULT_CLUSTER_NAME)
+            raise CtlError, errmsg
+
+    return cluster_name
+
+def get_cluster_nodes(cluster_name, parent=None):
+    success, output, k = query_nodes(parent)
+    if not success:
+        raise CtlError, output
+
+    nodes = []
+
+    buffer = StringIO(output)
+
+    for line in buffer:
+        if line.startswith('#'):
+            continue
+
+        try:
+            name, cluster, node, ip_address, ip_port, state = line.split(':')
+        except ValueError:
+            continue
+
+        if cluster == cluster_name:
+            info = {}
+            symtab = locals()
+
+            for sym in 'name', 'node', 'ip_address', 'ip_port':
+                info[sym] = symtab[sym]
+
+            nodes.append(info)
+
+    return nodes
+
+def main():
+    success, output, k = init_load()
+    if success:
+        print 'Success:\n' + output
+    else:
+        print 'Failed:\n' + output
+
+    success, output, k = query_nodes()
+    if success:
+        print 'Success:\n' + output
+    else:
+        print 'Failed:\n' + output
+
+if __name__ == '__main__':
+    main()

Modified: trunk/ocfs2console/ocfs2interface/pushconfig.py
===================================================================
--- trunk/ocfs2console/ocfs2interface/pushconfig.py	2005-04-14 21:02:58 UTC (rev 805)
+++ trunk/ocfs2console/ocfs2interface/pushconfig.py	2005-04-14 21:13:32 UTC (rev 806)
@@ -17,13 +17,34 @@
 
 import gobject
 
+import o2cb_ctl
+
 from terminal import TerminalDialog, terminal_ok as push_config_ok
 
 CONFIG_FILE = '/etc/ocfs2/cluster.conf'
 
-def push_config(parent):
-    commands = generate_commands(hosts)
+def get_hosts(parent=None):
+    cluster_name = o2cb_ctl.get_active_cluster_name(parent)
 
+    nodes = o2cb_ctl.get_cluster_nodes(cluster_name, parent)
+
+    return [node['name'] for node in nodes]
+
+def generate_commands(hosts):
+    hosts = get_hosts(parent)
+
+    commands = []
+
+    for host in hosts:
+        command = None
+
+def push_config(parent=None):
+    try:
+        commands = generate_commands(hosts)
+    except o2cb_ctl.CtlError, e:
+        error_box(parent, str(e))
+        return
+
     title = 'Propagate Cluster Configuration'
 
     dialog = TerminalDialog(parent=parent, title=title)



More information about the Ocfs2-tools-commits mailing list