[Cluster-devel] conga luci/cluster/index_html luci/docs/user_m ...

rmccabe at sourceware.org rmccabe at sourceware.org
Wed Jun 27 08:14:25 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe at sourceware.org	2007-06-27 08:14:23

Modified files:
	luci/cluster   : index_html 
	luci/docs      : user_manual.html 
	luci/site/luci/Extensions: HelperFunctions.py LuciDB.py 
	                           RicciQueries.py cluster_adapters.py 
	                           ricci_communicator.py 
	                           storage_adapters.py 
	luci/site/luci/Extensions/ClusterModel: ModelBuilder.py 
	luci/site/luci/var: Data.fs 
	luci/storage   : form-macros index_html 
	ricci/modules/storage: FSController.cpp FSController.h Makefile 
	                       StorageModule.cpp 
Added files:
	ricci/test_suite/storage: get_fs_group_members.xml 

Log message:
	Sync with the RHEL5 branch

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/index_html.diff?cvsroot=cluster&r1=1.34&r2=1.35
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/docs/user_manual.html.diff?cvsroot=cluster&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/HelperFunctions.py.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciDB.py.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/RicciQueries.py.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.257&r2=1.258
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_communicator.py.diff?cvsroot=cluster&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/storage_adapters.py.diff?cvsroot=cluster&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/var/Data.fs.diff?cvsroot=cluster&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&r1=1.21&r2=1.22
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/index_html.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/FSController.cpp.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/FSController.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/Makefile.diff?cvsroot=cluster&r1=1.12&r2=1.13
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/StorageModule.cpp.diff?cvsroot=cluster&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/test_suite/storage/get_fs_group_members.xml.diff?cvsroot=cluster&r1=1.1&r2=1.2

--- conga/luci/cluster/index_html	2007/06/25 16:11:30	1.34
+++ conga/luci/cluster/index_html	2007/06/27 08:14:12	1.35
@@ -44,7 +44,7 @@
 			<tal:block tal:condition="firsttime">
 				<tal:block tal:define="global busywaiting python:True" />
 				<meta http-equiv="refresh"
-					tal:attributes="content isBusy/refreshurl | string:." />
+					tal:attributes="content isBusy/refreshurl | python:'3%surl=/luci/cluster' % chr(0x3b)" />
 			</tal:block>
 
 			<tal:block tal:define="global busy isBusy/busy | nothing" />
@@ -52,7 +52,7 @@
 			<tal:block tal:condition="busy">
 				<tal:block tal:define="global busywaiting python:True" />
 				<meta http-equiv="refresh"
-					tal:attributes="content isBusy/refreshurl | string:." />
+					tal:attributes="content isBusy/refreshurl | python:'3%surl=/luci/cluster' % chr(0x3b)" />
 			</tal:block>
 		</tal:block>
     </metal:headslot>
--- conga/luci/docs/user_manual.html	2007/01/15 21:41:12	1.16
+++ conga/luci/docs/user_manual.html	2007/06/27 08:14:12	1.17
@@ -40,7 +40,8 @@
     can be started with the command "service luci start". The first time the
     server is started, it is initialized by generating https SSL certificates
     for that server and an initial password for the admin user is generated as a
-    random value. The admin password can be set any time by running the
+    random value. The admin password can be set any time by first stopping
+    the luci service with 'service luci stop, and then running the
     /usr/sbin/luci_admin application and specifying "password" on the command
     line. luci_admin can be run before luci is started for the first time to set
     up an initial password for the admin account. Other utilities available from
--- conga/luci/site/luci/Extensions/HelperFunctions.py	2007/06/25 16:03:38	1.7
+++ conga/luci/site/luci/Extensions/HelperFunctions.py	2007/06/27 08:14:13	1.8
@@ -18,11 +18,13 @@
 	return '%s; %s' % (str1, str2)
 
 class Worker(threading.Thread):
-	def __init__(self, mutex, hosts, riccis):
+	def __init__(self, mutex, hosts, riccis, func=None, *args):
 		threading.Thread.__init__(self)
 		self.mutex = mutex
 		self.hosts = hosts
 		self.riccis = riccis
+		self.query_func = func
+		self.query_args = args
 
 	def run(self):
 		while True:
@@ -32,21 +34,45 @@
 				return
 			host = self.hosts.pop()
 			self.mutex.release()
-			r = None
+
+			r = { 'ricci': None }
 
 			try:
-				r = RicciCommunicator(host)
+				rc = RicciCommunicator(host)
+				r['ricci'] = rc
+
+				if self.query_func is not None:
+					if self.query_args:
+						args = list(self.query_args)
+					else:
+						args = list()
+					args.insert(0, rc)
+					r['batch_result'] = self.query_func(*args)
 			except Exception, e:
-				#print host, 'failed', str(e)
-				pass
-			except:
-				#print host, 'failed'
 				pass
 
 			self.mutex.acquire()
 			self.riccis[host] = r
 			self.mutex.release()
 
+def send_batch_to_hosts(system_list, max_threads, func, *args):
+	mutex = threading.RLock()
+	threads = list()
+	hosts = list()
+	num_hosts = 0
+	ret = {}
+
+	for host in system_list:
+		hosts.append(host)
+		num_hosts += 1
+		if num_hosts <= max_threads:
+			threads.append(Worker(mutex, hosts, ret, func, *args))
+	for thread in threads:
+		thread.start()
+	for thread in threads:
+		thread.join()
+	return ret
+
 def get_system_info(self, system_list):
 	mutex = threading.RLock()
 	hive  = [] # workers
@@ -72,7 +98,7 @@
 		trusted = ''
 		authed = False
 		trusted = False
-		ricci = ss[hostname]
+		ricci = ss[hostname]['ricci']
 
 		if ricci is not None:
 			OS = ricci.os()
--- conga/luci/site/luci/Extensions/LuciDB.py	2007/06/25 16:03:38	1.2
+++ conga/luci/site/luci/Extensions/LuciDB.py	2007/06/27 08:14:13	1.3
@@ -158,7 +158,7 @@
 			return True
 
 		batch_id = item[1].getProperty(BATCH_ID)
-		batch_ret = rq.checkBatch(rc, batch_id)
+		batch_ret = rc.batch_status(batch_id)
 		finished = batch_ret[0]
 		if finished is True or finished == -1:
 			if finished == -1:
--- conga/luci/site/luci/Extensions/RicciQueries.py	2007/06/25 16:03:38	1.2
+++ conga/luci/site/luci/Extensions/RicciQueries.py	2007/06/27 08:14:13	1.3
@@ -6,52 +6,12 @@
 # Free Software Foundation.
 
 from xml.dom import minidom
-from ricci_communicator import RicciCommunicator, extract_module_status
+from ricci_communicator import RicciCommunicator
 from LuciSyslog import get_logger
 from conga_constants import LUCI_DEBUG_MODE
 
 luci_log = get_logger()
 
-def checkBatch(rc, batch_id):
-	err_msg = 'An unknown Ricci error occurred on %s' % rc.hostname()
-
-	try:
-		batch = rc.batch_report(batch_id)
-		if batch is None:
-			if LUCI_DEBUG_MODE is True:
-				luci_log.debug_verbose('checkBatch0: batch id %s not found' \
-					% batch_id)
-			return (True, 'batch id %s was not found' % batch_id)
-	except Exception, e:
-		if LUCI_DEBUG_MODE is True:
-			luci_log.debug_verbose('checkBatch1: %s: %r %s' \
-				% (rc.hostname(), e, str(e)))
-		return (-1, err_msg)
-
-	try:
-		code, new_err_msg = extract_module_status(batch, 1)
-		if new_err_msg:
-			err_msg = 'A Ricci error occurred on %s: %s' \
-				% (rc.hostname(), str(new_err_msg))
-	except Exception, e:
-		if LUCI_DEBUG_MODE is True:
-			luci_log.debug_verbose('checkBatch2: %s: %r %s' \
-				% (rc.hostname(), e, str(e)))
-		return (-1, err_msg)
-
-	# In progress.
-	if code == -101 or code == -102:
-		return (False, 'in progress')
-
-	# Done successfully.
-	if code == 0:
-		return (True, 'completed sucessfully')
-
-	# Error
-	if LUCI_DEBUG_MODE is True:
-		luci_log.debug_verbose('checkBatch3: %d: %s' % (code, rc.hostname()))
-	return (-1, err_msg)
-
 def addClusterNodeBatch(cluster_name,
 						install_base,
 						install_services,
@@ -310,9 +270,9 @@
 
 	for i in batch:
 		try:
-			batch_number = i.getAttribute('batch_id')
-			result = i.getAttribute('status')
-			return (str(batch_number), str(result))
+			batch_number = str(i.getAttribute('batch_id'))
+			result = str(i.getAttribute('status'))
+			return (batch_number, result)
 		except Exception, e:
 			if LUCI_DEBUG_MODE is True:
 				luci_log.debug_verbose('BAR1: %s' % e)
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2007/06/25 16:11:30	1.257
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2007/06/27 08:14:13	1.258
@@ -641,7 +641,7 @@
 	# abort the whole process.
 	try:
 		while True:
-			batch_ret = rq.checkBatch(cluster_ricci, batch_number)
+			batch_ret = cluster_ricci.batch_status(batch_number)
 			code = batch_ret[0]
 			if code is True:
 				break
@@ -2592,8 +2592,7 @@
 	54: validateFenceEdit,
 	55: validateDaemonProperties,
 	57: deleteFenceDevice,
-	58: validateNodeFenceConfig,
-	90: validate_svc_update
+	58: validateNodeFenceConfig
 }
 
 def validatePost(self, request):
@@ -3108,7 +3107,7 @@
 
 			if rc is not None:
 				batch_num = item[1].getProperty(BATCH_ID)
-				batch_res = rq.checkBatch(rc, batch_num)
+				batch_res = rc.batch_status(batch_num)
 				finished = batch_res[0]
 				err_msg = batch_res[1]
 
--- conga/luci/site/luci/Extensions/ricci_communicator.py	2007/06/25 16:03:39	1.26
+++ conga/luci/site/luci/Extensions/ricci_communicator.py	2007/06/27 08:14:13	1.27
@@ -53,7 +53,10 @@
 					% (self.__hostname, hello.toxml()))
 		except:
 			if LUCI_DEBUG_MODE is True:
-				luci_log.debug_verbose('RC:init0: error receiving header from %s: %r %s' % (self.__hostname, e, str(e)))
+				luci_log.debug_verbose('RC:init0: error receiving header from %s:%d: %r %s' % (self.__hostname, self.__port, e, str(e)))
+			else:
+				luci_log.info('Error reading from %s:%d: %s' \
+					% (self.__hostname, self.__port, str(e)))
 
 		self.__authed = hello.firstChild.getAttribute('authenticated') == 'true'
 		self.__cluname = hello.firstChild.getAttribute('clustername')
@@ -231,8 +234,8 @@
 		if doc.firstChild.getAttribute('success') != '0':
 			if LUCI_DEBUG_MODE is True:
 				luci_log.debug_verbose('RC:PB4: batch command failed')
-			raise RicciError, 'The last ricci command to host %s failed' \
-					% self.__hostname
+			raise RicciError, 'The last ricci command to host %s:%d failed' \
+					% (self.__hostname, self.__port)
 
 		batch_node = None
 		for node in doc.firstChild.childNodes:
@@ -243,8 +246,8 @@
 			if LUCI_DEBUG_MODE is True:
 				luci_log.debug_verbose('RC:PB5: no <batch/> from %s' \
 					% self.__hostname)
-			raise RicciError, 'missing <batch/> in ricci response from "%s"' \
-					% self.__hostname
+			raise RicciError, 'missing <batch/> in ricci response from %s:%d' \
+					% (self.__hostname, self.__port)
 
 		return batch_node
 
@@ -264,7 +267,7 @@
 			ricci_xml = self.process_batch(batch_xml, async)
 			if LUCI_DEBUG_NET is True:
 				try:
-					luci_log.debug_net_priv('RC:BRun2: received XML "%s" from host %s in response to batch command.' % (ricci_xml.toxml(), self.__hostname))
+					luci_log.debug_net_priv('RC:BRun2: received XML "%s" from host %s in response to batch command' % (ricci_xml.toxml(), self.__hostname))
 				except:
 					pass
 		except:
@@ -276,6 +279,48 @@
 		doc.appendChild(ricci_xml)
 		return doc
 
+	def batch_status(self, batch_id):
+		err_msg = 'An unknown ricci error occurred on %s:%d' \
+					% (self.__hostname, self.__port)
+
+		try:
+			batch = self.batch_report(batch_id)
+			if batch is None:
+				if LUCI_DEBUG_MODE is True:
+					luci_log.debug_verbose('RCCB0: batch id %s not found' \
+						% batch_id)
+				return (True, 'batch id %s was not found' % batch_id)
+		except Exception, e:
+			if LUCI_DEBUG_MODE is True:
+				luci_log.debug_verbose('RCCB1: %s:%d: %r %s' \
+					% (self.__hostname, self.__port, e, str(e)))
+			return (-1, err_msg)
+
+		try:
+			code, new_err_msg = extract_module_status(batch, 1)
+			if new_err_msg:
+				err_msg = 'A ricci error occurred on %s:%d: %s' \
+							% (self.__hostname, self.__port, str(new_err_msg))
+		except Exception, e:
+			if LUCI_DEBUG_MODE is True:
+				luci_log.debug_verbose('RCCB2: %s:%d %r %s: %s' \
+					% (self.__hostname, self.__port, e, str(e), err_msg))
+			return (-1, err_msg)
+
+		# In progress.
+		if code == -101 or code == -102:
+			return (False, 'in progress')
+
+		# Done successfully.
+		if code == 0:
+			return (True, 'completed sucessfully')
+
+		# Error
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('RCCB3: %s:%d code %d: %s' \
+				% (self.__hostname, self.__port, code, err_msg))
+		return (-1, err_msg)
+
 	def batch_report(self, batch_id):
 		if LUCI_DEBUG_NET is True:
 			luci_log.debug_net('RC:BRep0: [auth=%d] asking for batchid# %s for host %s' % (self.__authed, batch_id, self.__hostname))
@@ -374,6 +419,9 @@
 		return doc
 
 def get_ricci_communicator(self, hostname, allowed_systems):
+	if not hostname:
+		return None
+
 	if not self.access_to_host_allowed(hostname, allowed_systems):
 		if LUCI_DEBUG_MODE is True:
 			luci_log.debug_verbose('GRC0: access to host %s is not allowed' % hostname)
--- conga/luci/site/luci/Extensions/storage_adapters.py	2007/06/25 16:03:39	1.10
+++ conga/luci/site/luci/Extensions/storage_adapters.py	2007/06/27 08:14:13	1.11
@@ -10,9 +10,13 @@
 	PT_MAPPER_TYPE, PT_PATH, STONAME, STORAGE, STORAGESYS, \
 	VIEW_BD, VIEW_BDS, VIEW_MAPPER, VIEW_MAPPERS
 
-from ricci_defines import MAPPER_SYS_TYPE, MAPPER_VG_TYPE, SYSTEM_PREFIX, VG_PREFIX
+from ricci_defines import MAPPER_SYS_TYPE, MAPPER_VG_TYPE, \
+	SYSTEM_PREFIX, VG_PREFIX
+
 from LuciZope import get_systems_statuses
 
+from StorageReport import invalidate_storage_report
+
 def createStorageChooser(self, request, systems):
   dummynode = {}
 
@@ -29,6 +33,15 @@
   except KeyError, e:
     url = "."
 
+  if stoname and request.has_key('reprobe_storage'):
+    try:
+      invalidate_storage_report(request.SESSION, stoname)
+      redirect_url = '%s?%s' % (request['ACTUAL_URL'], request['QUERY_STRING'])
+      redirect_url = redirect_url.replace('&reprobe_storage=true', '')
+      request.RESPONSE.redirect(redirect_url)
+    except:
+      pass
+
   try:
     pagetype = request[PAGETYPE]
   except KeyError, e:
--- conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py	2007/06/25 16:03:39	1.2
+++ conga/luci/site/luci/Extensions/ClusterModel/ModelBuilder.py	2007/06/27 08:14:13	1.3
@@ -507,6 +507,9 @@
   def getNodeNames(self):
     return map(lambda x: x.getName(), self.clusternodes_ptr.getChildren())
 
+  def getNodeNameById(self, node_id):
+    return filter(lambda x: x.getAttribute('nodeid') == node_id, self.clusternodes_ptr.getChildren())[0].getName()
+
   def addNode(self, clusternode):
     self.clusternodes_ptr.addChild(clusternode)
     if self.usesMulticast is True:
Binary files /cvs/cluster/conga/luci/site/luci/var/Data.fs	2007/06/25 16:03:39	1.26 and /cvs/cluster/conga/luci/site/luci/var/Data.fs	2007/06/27 08:14:13	1.27 differ
rcsdiff: /cvs/cluster/conga/luci/site/luci/var/Data.fs: diff failed
--- conga/luci/storage/form-macros	2007/06/25 16:03:41	1.21
+++ conga/luci/storage/form-macros	2007/06/27 08:14:22	1.22
@@ -103,7 +103,7 @@
         tal:define="batch_id     python:here.apply_storage_changes(ricci, storage_report, request); 
                     check_URL    context/storage/check-batch/absolute_url; 
                     check_url    python:check_URL + '?storagename=' + storagename + '&batch_id=' + batch_id">
-   <div metal:use-macro="here/form-macros/macros/display-commiting-changes"/>
+   <div metal:use-macro="here/form-macros/macros/display-committing-changes"/>
    <form id="urls_form">
     <input tal:attributes="type  string:hidden;
                            name  string:check_url;
@@ -148,7 +148,7 @@
          } else {
            m = msg;
          }
-         alert('An error has occured while commiting changes:\n\n' + m);
+         alert('An error has occured while committing changes:\n\n' + m);
          window.location = err_url;
       }
     } else {
@@ -179,7 +179,7 @@
 
 
 
-<div metal:define-macro="display-commiting-changes">
+<div metal:define-macro="display-committing-changes">
    <table style="width: 100%;">
     <tr>
      <td align="center">
@@ -188,7 +188,7 @@
     </tr>
     <tr>
      <td align="center">
-      <div style="padding-bottom: 4cm;">Commiting Changes</div>
+      <div style="padding-bottom: 4cm;">Committing Changes</div>
      </td>
     </tr>
    </table>
@@ -266,11 +266,11 @@
        <td>
         <select name="preferred_size_units" onchange="this.form.submit()">
          <option value="MB" 
-                 tal:attributes="selected python:preferred_size_units == 'MB'">MB - MegaBytes</option>
+                 tal:attributes="selected python:preferred_size_units == 'MB'">MB - Megabytes</option>
          <option value="GB" 
-                 tal:attributes="selected python:preferred_size_units == 'GB'">GB - GigaBytes</option>
+                 tal:attributes="selected python:preferred_size_units == 'GB'">GB - Gigabytes</option>
          <option value="TB" 
-                 tal:attributes="selected python:preferred_size_units == 'TB'">TB - TeraBytes</option>
+                 tal:attributes="selected python:preferred_size_units == 'TB'">TB - Terabytes</option>
         </select>
        </td>
       </tr>
--- conga/luci/storage/index_html	2007/06/25 16:03:41	1.8
+++ conga/luci/storage/index_html	2007/06/27 08:14:22	1.9
@@ -174,7 +174,7 @@
                         global storage_report nothing"/>
       <span tal:omit-tag=""
             tal:condition="storagename"
-            tal:define="report_cached python:here.is_storage_report_cached(request.SESSION, storagename)">
+            tal:define="global report_cached python:here.is_storage_report_cached(request.SESSION, storagename)">
        <span tal:omit-tag=""
              tal:condition="report_cached">
         <span tal:omit-tag=""
@@ -216,11 +216,20 @@
                       <h1 tal:content="storagename"></h1>
                     </span>
                   </div>
+				<metal:main-form-content use-macro="here/form-chooser/macros/main-form" />
+				<div style="padding-top: 10px;"
+					tal:condition="python: report_cached and not (request.has_key('pagetype') and request['pagetype']=='commit_changes')">
+					<form>
+						<input type="hidden" name="reprobe_url"
+							tal:attributes="value
+								python:'%s?%s&reprobe_storage=true' % (request['ACTUAL_URL'], request['QUERY_STRING'])" />
+						<input class="form_button" type="button" name="reprobe"
+							value="Reprobe Storage"
+							onclick="javascript:location=this.form.reprobe_url.value;" />
+					</form>
+				</div>
                 </div>
               </metal:block>
-              <metal:main-form-content use-macro="here/form-chooser/macros/main-form">
-                <h1>Future Site of Forms</h1>
-              </metal:main-form-content>
             </td>
             <tal:comment replace="nothing"> End of main content block </tal:comment>
           </tr>
--- conga/ricci/modules/storage/FSController.cpp	2006/09/26 03:20:47	1.7
+++ conga/ricci/modules/storage/FSController.cpp	2007/06/27 08:14:23	1.8
@@ -1,5 +1,5 @@
 /*
-  Copyright Red Hat, Inc. 2005
+  Copyright Red Hat, Inc. 2005-2007
 
   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
@@ -20,7 +20,6 @@
  * Author: Stanko Kupcevic <kupcevic at redhat.com>
  */
 
-
 #include "FSController.h"
 #include "ExtendedFS.h"
 #include "SwapFS.h"
@@ -28,10 +27,32 @@
 #include "GFS2.h"
 #include "UnsupportedFS.h"
 #include "utils.h"
-
+#include <errno.h>
+#include <libgroup.h>
 
 using namespace std;
 
+std::list<String>
+FSController::get_fs_group_ids(const String& name)
+{
+	list<String> members;
+	group_data_t fsgroup;
+
+	if (group_get_group(2, name.c_str(), &fsgroup) != 0)
+		throw String("error retrieving group members for " + name + ": " + strerror(errno));
+
+	if (!fsgroup.member)
+		throw String("the local node does not have " + name + " mounted");
+
+	for (int i = 0 ; i < fsgroup.member_count ; i++) {
+		char buf[8];
+		int ret = snprintf(buf, sizeof(buf), "%d", fsgroup.members[i]);
+		if (ret < 1 || (size_t) ret >= sizeof(buf))
+			throw String("invalid node id");
+    	members.push_back(String(buf));
+	}
+	return members;
+}
 
 counting_auto_ptr<Content> 
 FSController::get_fs(const String& path)
--- conga/ricci/modules/storage/FSController.h	2006/08/10 22:53:09	1.2
+++ conga/ricci/modules/storage/FSController.h	2007/06/27 08:14:23	1.3
@@ -33,7 +33,8 @@
 class FSController
 {
  public:
-  
+  std::list<String> get_fs_group_ids(const String& name);
+ 
   counting_auto_ptr<Content> get_fs(const String& path);
   
   std::list<counting_auto_ptr<ContentTemplate> > get_available_fss();
--- conga/ricci/modules/storage/Makefile	2006/09/26 03:17:41	1.12
+++ conga/ricci/modules/storage/Makefile	2007/06/27 08:14:23	1.13
@@ -56,7 +56,7 @@
 
 INCLUDE    += 
 CXXFLAGS   += 
-LDFLAGS    += -lmagic
+LDFLAGS    += -lgroup -lmagic
 
 all: ${TARGET}
 
--- conga/ricci/modules/storage/StorageModule.cpp	2006/12/12 13:11:51	1.6
+++ conga/ricci/modules/storage/StorageModule.cpp	2007/06/27 08:14:23	1.7
@@ -25,6 +25,7 @@
 #include "MapperFactory.h"
 #include "BDFactory.h"
 #include "LVM.h"
+#include "FSController.h"
 
 
 using namespace std;
@@ -47,6 +48,7 @@
 static VarMap get_bd(const VarMap& args);
 static VarMap modify_bd(const VarMap& args);
 static VarMap remove_bd(const VarMap& args);
+static VarMap get_fs_group_members(const VarMap& args);
 
 static VarMap enable_clustered_lvm(const VarMap& args);
 static VarMap disable_clustered_lvm(const VarMap& args);
@@ -83,6 +85,8 @@
   api_1_0["get_bd"]                             = get_bd;
   api_1_0["modify_bd"]                          = modify_bd;
   api_1_0["remove_bd"]                          = remove_bd;
+
+  api_1_0["get_fs_group_members"]                   = get_fs_group_members;
   
   api_1_0["enable_clustered_lvm"]                 = enable_clustered_lvm;
   api_1_0["disable_clustered_lvm"]                = disable_clustered_lvm;
@@ -416,8 +420,36 @@
   return ret;
 }
 
+VarMap 
+get_fs_group_members(const VarMap& args)
+{
+  String fsname;
+  try {
+    VarMap::const_iterator iter = args.find("fsname");
+    if (iter == args.end())
+      throw APIerror("missing fsname variable");
+    fsname = iter->second.get_string();
+    if (fsname == "")
+		throw APIerror("missing fsname value");
+  } catch ( String e ) {
+    throw APIerror(e);
+  }
 
+  list<XMLObject> ids_list;
+  list<String> group_ids = FSController().get_fs_group_ids(fsname);
+
+  for (list<String>::iterator iter = group_ids.begin() ; iter != group_ids.end() ; iter++)
+  {
+	XMLObject id_xml("group_member");
+	id_xml.set_attr("nodeid", String(*iter));
+	ids_list.push_back(id_xml);
+  }
 
+  Variable var("group_member_list", ids_list);
+  VarMap ret;
+  ret.insert(pair<String, Variable>(var.name(), var));
+  return ret;
+}
 
 
 list<XMLObject> 
--- conga/ricci/test_suite/storage/get_fs_group_members.xml	2007/06/25 19:10:55	1.1
+++ conga/ricci/test_suite/storage/get_fs_group_members.xml	2007/06/27 08:14:23	1.2
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<ricci version="1.0" function="process_batch" async="false">
+	<batch>
+		<module name="storage">
+			<request sequence="1254" API_version="1.0">
+				<function_call name="get_fs_group_members" >
+					<var mutable="false" name="fsname" value="gfsname" type="string" />
+				</function_call>
+			</request>
+		</module>
+	</batch>
+</ricci>
+




More information about the Cluster-devel mailing list