[Cluster-devel] conga/luci cluster/form-macros site/luci/Exten ...

rmccabe at sourceware.org rmccabe at sourceware.org
Thu Feb 8 03:46:52 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Branch: 	RHEL4
Changes by:	rmccabe at sourceware.org	2007-02-08 03:46:51

Modified files:
	luci/cluster   : form-macros 
	luci/site/luci/Extensions: FailoverDomain.py ModelBuilder.py 
	                           cluster_adapters.py 
Added files:
	luci/cluster   : validate_fdom.js 
	luci/site/luci/Extensions: FenceXVMd.py 

Log message:
	Support for adding and editing failover domains (bz 215014)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_fdom.js.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.3.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.176.2.4&r2=1.176.2.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/FenceXVMd.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=NONE&r2=1.1.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/FailoverDomain.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.1&r2=1.1.4.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ModelBuilder.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.19.2.2&r2=1.19.2.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.227.2.3&r2=1.227.2.4

/cvs/cluster/conga/luci/cluster/validate_fdom.js,v  -->  standard output
revision 1.3.2.1
--- conga/luci/cluster/validate_fdom.js
+++ -	2007-02-08 03:46:51.751330000 +0000
@@ -0,0 +1,40 @@
+function fdom_set_prioritized(form, state) {
+	var prilist = form.getElementsByTagName('input');
+	if (!prilist)
+		return (-1);
+	for (var i = 0 ; i < prilist.length ; i++) {
+		if (prilist[i].type == 'text' && prilist[i].className == 'fdom_priority')
+			prilist[i].disabled = !state || !form[prilist[i].id][0].checked;
+	}
+}
+
+function fdom_set_member(form, name, state) {
+	var prioritized = document.getElementById('prioritized');
+	if (!prioritized)
+		return (-1);
+	prioritized = prioritized.checked;
+	var member_pri_elem = document.getElementById(name);
+	if (!member_pri_elem)
+		return (-1);
+	member_pri_elem.disabled = !prioritized || !state;
+}
+
+function validate_add_fdom(form) {
+	var errors = new Array();
+
+	if (!form.name || str_is_blank(form.name.value)) {
+		set_form_err(form.name);
+		errors.append('No name was given for this failover domain.');
+	} else
+		clr_form_err(form.name);
+
+	if (error_dialog(errors))
+		return (-1);
+
+	var confirm_msg = 'Add this failover domain?';
+	if (form.oldname)
+		confirm_msg = 'Update this failover domain?';
+
+	if (confirm(confirm_msg))
+		form.submit();
+}
--- conga/luci/cluster/form-macros	2007/02/07 18:30:53	1.176.2.4
+++ conga/luci/cluster/form-macros	2007/02/08 03:46:51	1.176.2.5
@@ -4322,23 +4322,117 @@
 	</div>
 </div>
 
+<tal:block metal:define-macro="fdom-macro">
+<script type="text/javascript"
+	src="/luci/homebase/homebase_common.js">
+</script>
+<script type="text/javascript"
+	src="/luci/cluster/validate_fdom.js">
+</script>
+
+<form method="post" action="">
+	<input type="hidden" name="clustername"
+		tal:attributes="value request/clustername | nothing" />
+	<input type="hidden" name="pagetype"
+		tal:attributes="value request/pagetype | nothing" />
+	<input type="hidden" name="oldname"
+		tal:condition="exists: fdom/name"
+		tal:attributes="value fdom/name | nothing" />
+	
+	<table class="systemsTable" width="100%">
+		<thead class="systemsTable">
+			<tr class="systemsTable">
+				<td><strong>Failover Domain Name</strong></td>
+				<td>
+					<input type="text" name="name"
+						tal:attributes="value fdom/name | nothing" />
+				</td>
+			</tr>
+			<tr class="systemsTable">
+				<td>Prioritized</td>
+				<td>
+					<input type="checkbox" name="prioritized" id="prioritized"
+						onchange="fdom_set_prioritized(this.form, this.checked)"
+						tal:attributes="checked python: (fdom and 'prioritized' in fdom and fdom['prioritized'] == '1') and 'checked' or ''" />
+				</td>
+			</tr>
+			<tr class="systemsTable">
+				<td>Restrict failover to this domain's members</td>
+				<td>
+					<input type="checkbox" name="restricted"
+						tal:attributes="checked python: (fdom and 'restricted' in fdom and fdom['restricted'] == '1') and 'checked' or ''" />
+				</td>
+			</tr>
+			<tr class="systemsTable">
+				<td class="systemsTable" colspan="2">
+					<p></p>
+					<p class="reshdr">Failover domain membership</p>
+				</td>
+			</tr>
+		</thead>
+
+		<tfoot class="systemsTable">
+			<tr class="systemsTable"><td>
+				<div class="hbSubmit">
+					<input type="button" name="add" value="Submit"
+						onclick="validate_add_fdom(this.form)" />
+				</div>
+			</td></tr>
+		</tfoot>
+
+		<tbody width="60%">
+			<tr class="systemsTable">
+				<th class="systemsTable" width="33%">Node</th>
+				<th class="systemsTable" width="10%">Member</th>
+				<th class="systemsTable" width="57%">Priority</th>
+			</tr>
+			<tal:block tal:repeat="n python:here.getnodes(modelb)">
+				<tr class="systemsTable">
+					<td class="systemsTable" width="33%">
+						<tal:block tal:replace="n" />
+					<td class="systemsTable" width="10%">
+						<input type="checkbox"
+							onchange="fdom_set_member(this.form, this.name, this.checked)"
+							tal:attributes="
+								checked python: ('members' in fdom and n in fdom['members']) and 'checked' or '';
+								name n" />
+					</td>
+					<td class="systemsTable" width="75%">
+						<input type="text" class="fdom_priority"
+							tal:attributes="
+								id n;
+								name python: '__PRIORITY__' + n;
+								value python: ('members' in fdom and n in fdom['members'] and 'priority' in fdom['members'][n]) and fdom['members'][n]['priority'] or '1';
+								disabled python: (not fdom or not 'prioritized' in fdom or fdom['prioritized'] != '1' or not 'members' in fdom or not n in fdom['members']) and 'disabled' or ''" />
+					</td>
+				</tr>
+			</tal:block>
+		</tbody>
+	</table>
+</form>
+
+</tal:block>
+
 <div metal:define-macro="fdomadd-form">
 	<script type="text/javascript">
 		set_page_title('Luci — cluster — failover domains — Add a failover domain');
 	</script>
-	<h2>Failover Domain Add Form</h2>
-  <tal:block tal:define="allnodes python:here.getFdomNodes(request)"/>
+
+	<h2>Add a Failover Domain</h2>
+	<tal:block metal:use-macro="here/form-macros/macros/fdom-macro" />
 </div>
 
 <div metal:define-macro="fdomconfig-form">
 	<script type="text/javascript">
 		set_page_title('Luci — cluster — failover domains — Configure a failover domain');
 	</script>
-	<h2>Failover Domain Configuration Form</h2>
 </div>
 
 <div metal:define-macro="fdom-form">
 	<h2>Failover Domain Form</h2>
+	<tal:block tal:define="fdom python:here.getFdomInfo(modelb, request)">
+		<tal:block metal:use-macro="here/form-macros/macros/fdom-macro" />
+	</tal:block>
 </div>
 
 <div metal:define-macro="fdomprocess-form">
/cvs/cluster/conga/luci/site/luci/Extensions/FenceXVMd.py,v  -->  standard output
revision 1.1.2.1
--- conga/luci/site/luci/Extensions/FenceXVMd.py
+++ -	2007-02-08 03:46:51.952546000 +0000
@@ -0,0 +1,14 @@
+import string
+from TagObject import TagObject
+
+TAG_NAME = "fence_xvmd"
+
+class FenceXVMd(TagObject):
+  def __init__(self):
+    TagObject.__init__(self)
+    self.TAG_NAME = TAG_NAME
+    #Have autostart set by default
+
+  def getProperties(self):
+    stringbuf = ""
+    return stringbuf
--- conga/luci/site/luci/Extensions/FailoverDomain.py	2006/05/30 20:17:21	1.1
+++ conga/luci/site/luci/Extensions/FailoverDomain.py	2007/02/08 03:46:51	1.1.4.1
@@ -22,7 +22,7 @@
   def getProperties(self):
     stringbuf = ""
     restricted_status = ""
-    ordereded_status = ""
+    ordered_status = ""
     string_restricted = ""
     string_ordered = ""
     string_num_kin = ""
--- conga/luci/site/luci/Extensions/ModelBuilder.py	2007/02/07 17:02:18	1.19.2.2
+++ conga/luci/site/luci/Extensions/ModelBuilder.py	2007/02/08 03:46:51	1.19.2.3
@@ -627,10 +627,17 @@
       return list()
     else:
       return self.failoverdomains_ptr.getChildren()
-        
+
   def getFailoverDomainPtr(self):
     return self.failoverdomains_ptr
 
+  def getFailoverDomainByName(self, fdom_name):
+    fdoms = self.getFailoverDomains()
+    for i in fdoms:
+      if i.getName() == fdom_name:
+        return i
+    return None
+
   def getFailoverDomainsForNode(self, nodename):
     matches = list()
     faildoms = self.getFailoverDomains()
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2007/02/07 21:30:33	1.227.2.3
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2007/02/08 03:46:51	1.227.2.4
@@ -11,6 +11,8 @@
 from Ip import Ip
 from Clusterfs import Clusterfs
 from Fs import Fs
+from FailoverDomain import FailoverDomain
+from FailoverDomainNode import FailoverDomainNode
 from RefObject import RefObject
 from ClusterNode import ClusterNode
 from NFSClient import NFSClient
@@ -2009,6 +2011,143 @@
 
 	response.redirect(request['URL'] + "?pagetype=" + NODE + "&clustername=" + clustername + '&nodename=' + nodename + '&busyfirst=true')
 
+def validateFdom(self, request):
+	errors = list()
+
+	try:
+		model = request.SESSION.get('model')
+		if not model:
+			raise Exception, 'no model'
+	except Exception, e:
+		luci_log.debug_verbose('validateFdom0: no model: %s' % str(e))
+		return (False, {'errors': [ 'Unable to retrieve cluster information.' ]})
+
+	prioritized = False
+	try:
+		prioritized = request.form.has_key('prioritized')
+	except:
+		prioritized = False
+
+	restricted = False
+	try:
+		restricted = request.form.has_key('restricted')
+	except:
+		restricted = False
+
+	clustername = None
+	try:
+		clustername = request.form['clustername'].strip()
+		if not clustername:
+			raise Exception, 'blank'
+	except:
+		try:
+			clustername = model.getClusterName()
+			if not clustername:
+				raise Exception, 'blank'
+		except:
+			clustername = None
+
+	if not clustername:
+		errors.append('Unable to determine this cluster\'s name.')
+
+	try:
+		name = request.form['name'].strip()
+		if not name:
+			raise Exception, 'blank'
+	except Exception, e:
+		errors.append('No name was given for this failover domain.')
+		luci_log.debug_verbose('validateFdom0: %s' % str(e))
+
+	oldname = None
+	try:
+		oldname = request.form['oldname'].strip()
+		if not oldname:
+			raise Exception, 'blank'
+	except:
+		pass
+
+	if oldname is None or oldname != name:
+		if model.getFailoverDomainByName(name) is not None:
+			errors.append('A failover domain named \"%s\" already exists.' % name)
+
+	fdom = None
+	if oldname is not None:
+		fdom = model.getFailoverDomainByName(oldname)
+		if fdom is None:
+			luci_log.debug_verbose('validateFdom1: No fdom named %s exists' % oldname)
+			errors.append('No failover domain named \"%s" exists.' % oldname)
+		else:
+			fdom.addAttribute('name', name)
+			fdom.children = list()
+	else:
+		fdom = FailoverDomain()
+		fdom.addAttribute('name', name)
+
+	if fdom is None or len(errors) > 0:
+		return (False, {'errors': errors })
+
+	if prioritized:
+		fdom.addAttribute('ordered', '1')
+	else:
+		fdom.addAttribute('ordered', '0')
+
+	if restricted:
+		fdom.addAttribute('restricted', '1')
+	else:
+		fdom.addAttribute('restricted', '0')
+
+	cluster_nodes = map(lambda x: str(x.getName()), model.getNodes())
+
+	for i in cluster_nodes:
+		if request.form.has_key(i):
+			fdn = FailoverDomainNode()
+			fdn.addAttribute('name', i)
+			if prioritized:
+				priority = 1
+				try:
+					priority = int(request.form['__PRIORITY__' + i].strip())
+					if priority < 1:
+						priority = 1
+				except Exception, e:
+					priority = 1
+				fdn.addAttribute('priority', str(priority))
+			fdom.addChild(fdn)
+
+	try:
+		fdom_ptr = model.getFailoverDomainPtr()
+		if not oldname:
+			fdom_ptr.addChild(fdom)
+		model.setModified(True)
+		conf = str(model.exportModelAsString())
+	except Exception, e:
+		luci_log.debug_verbose('validateFdom2: %s' % str(e))
+		errors.append('Unable to update the cluster configuration.')
+
+	if len(errors) > 0:
+		return (False, {'errors': errors })
+
+	rc = getRicciAgent(self, clustername)
+	if not rc:
+		luci_log.debug_verbose('validateFdom3: unable to find a ricci agent for cluster %s' % clustername)
+		return (False, {'errors': ['Unable to find a ricci agent for the %s cluster' % clustername ]})
+	ragent = rc.hostname()
+
+	batch_number, result = setClusterConf(rc, conf)
+	if batch_number is None or result is None:
+		luci_log.debug_verbose('validateFdom4: missing batch and/or result')
+		return (False, {'errors': [ 'An error occurred while constructing the new cluster configuration.' ]})
+
+	try:
+		if oldname:
+			set_node_flag(self, clustername, ragent, str(batch_number), FDOM, 'Updating failover domain \"%s\"' % oldname)
+		else:
+			set_node_flag(self, clustername, ragent, str(batch_number), FDOM_ADD, 'Creating failover domain \"%s\"' % name)
+	except Exception, e:
+		luci_log.debug_verbose('validateFdom5: failed to set flags: %s' % str(e))
+
+	response = request.RESPONSE
+	response.redirect(request['URL'] + "?pagetype=" + FDOM + "&clustername=" + clustername + '&fdomname=' + name + '&busyfirst=true')
+
 def validateVM(self, request):
 	errors = list()
 
@@ -2122,6 +2261,8 @@
 	24: validateServiceAdd,
 	31: validateResourceAdd,
 	33: validateResourceAdd,
+	41: validateFdom,
+	44: validateFdom,
 	51: validateFenceAdd,
 	54: validateFenceEdit,
 	55: validateDaemonProperties,
@@ -2247,12 +2388,11 @@
   return dummynode
 
 def getnodes(self, model):
-  mb = model
-  nodes = mb.getNodes()
-  names = list()
-  for node in nodes:
-    names.append(node.getName())
-  return names
+	try:
+		return map(lambda x: str(x.getName()), model.getNodes())
+	except Exception, e:
+		luci_log.debug_verbose('getnodes0: %s' % str(e))
+	return []
 
 def createCluConfigTree(self, request, model):
   dummynode = {}
@@ -3370,6 +3510,39 @@
 	response = req.RESPONSE
 	response.redirect(req['URL'] + "?pagetype=" + SERVICE_LIST + "&clustername=" + cluname + '&busyfirst=true')
 
+def getFdomInfo(self, model, request):
+	fhash = {}
+	fhash['members'] = {}
+
+	try:
+		fdom = model.getFailoverDomainByName(request['fdomname'])
+	except Exception, e:
+		luci_log.debug_verbose('getFdomInfo0: %s' % str(e))
+		return fhash
+
+	fhash['name'] = fdom.getName()
+
+	ordered_attr = fdom.getAttribute('ordered')
+	if ordered_attr is not None and (ordered_attr == "true" or ordered_attr == "1"):
+		fhash['prioritized'] = '1'
+	else:
+		fhash['prioritized'] = '0'
+
+	restricted_attr = fdom.getAttribute('restricted')
+	if restricted_attr is not None and (restricted_attr == "true" or restricted_attr == "1"):
+		fhash['restricted'] = '1'
+	else:
+		fhash['restricted'] = '0'
+
+	nodes = fdom.getChildren()
+	for node in nodes:
+		try:
+			priority = node.getAttribute('priority')
+		except:
+			priority = '1'
+		fhash['members'][node.getName()] = { 'priority': priority }
+	return fhash
+
 def getFdomsInfo(self, model, request, clustatus):
   slist = list()
   nlist = list()
@@ -3386,7 +3559,7 @@
   for fdom in fdoms:
     fdom_map = {}
     fdom_map['name'] = fdom.getName()
-    fdom_map['cfgurl'] = baseurl + "?pagetype=" + FDOM_LIST + "&clustername=" + clustername
+    fdom_map['cfgurl'] = baseurl + "?pagetype=" + FDOM + "&clustername=" + clustername + '&fdomname=' + fdom.getName()
     ordered_attr = fdom.getAttribute('ordered')
     restricted_attr = fdom.getAttribute('restricted')
     if ordered_attr is not None and (ordered_attr == "true" or ordered_attr == "1"):




More information about the Cluster-devel mailing list