[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