[Cluster-devel] conga/luci/site/luci/Extensions homebase_adapt ...

rmccabe at sourceware.org rmccabe at sourceware.org
Fri Oct 6 18:58:52 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe at sourceware.org	2006-10-06 18:58:51

Modified files:
	luci/site/luci/Extensions: homebase_adapters.py 
	                           cluster_adapters.py 

Log message:
	- enforce os homogeneity when deploying a cluster
	- allow 1 node clusters (used to require 2)
	- fix a few cases where code was returning a string instead of a list

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/homebase_adapters.py.diff?cvsroot=cluster&r1=1.22&r2=1.23
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.83&r2=1.84

--- conga/luci/site/luci/Extensions/homebase_adapters.py	2006/10/04 13:25:48	1.22
+++ conga/luci/site/luci/Extensions/homebase_adapters.py	2006/10/06 18:58:51	1.23
@@ -9,6 +9,7 @@
 
 from ricci_defines import *
 from ricci_communicator import RicciCommunicator
+from cluster_adapters import resolveOSType
 
 HOMEBASE_ADD_USER="1"
 HOMEBASE_ADD_SYSTEM="2"
@@ -155,7 +156,7 @@
 		systemName = rc.system_name()
 	except:
 		error = 'Unable to establish a connection to the ricci agent on \"' + host + '\"'
-		return { 'host': host, 'ricci_host': systemName, 'errors': error, 'cur_auth': False }
+		return { 'host': host, 'ricci_host': systemName, 'errors': error, 'cur_auth': False, 'os': None }
 
 
 	if rc.authed():
@@ -163,17 +164,21 @@
 	else:
 		prevAuth = False
 		if not passwd:
-			return { 'host': host, 'ricci_host': systemName, 'prev_auth': False, 'cur_auth': False }
+			return { 'host': host, 'ricci_host': systemName, 'prev_auth': False, 'cur_auth': False, 'os': None}
 		else:
 			try:
 				rc.auth(passwd)
 			except: pass
 
 	if rc.authed():
+		os_str = resolveOSType(rc.os())
+		if os_str == None:
+			os_str = "rhel5"  #Backup plan in case all is almost lost...
+
 		systemName = rc.system_name()
 		if systemName[:9] == 'localhost' or systemName[:5] == '127.0':
 			systemName = host
-		node = { 'host': host, 'ricci_host': systemName, 'prev_auth': prevAuth, 'cur_auth': True }
+		node = { 'host': host, 'ricci_host': systemName, 'prev_auth': prevAuth, 'cur_auth': True, 'os': os_str }
 
 		cluster_info = rc.cluster_info()
 		if cluster and ((not cluster_info) or (cluster_info[0] != cluster)):
@@ -185,7 +190,7 @@
 		return node
 
 	error = 'Unable to authenticate to the ricci agent on \"' + host + '\"'
-	return { 'host': host, 'ricci_host': systemName, 'prev_auth': False , 'cur_auth': False, 'errors': error }
+	return { 'host': host, 'ricci_host': systemName, 'prev_auth': False , 'cur_auth': False, 'errors': error, 'os': None }
 
 def validateAddClusterInitial(self, request):
 	errors = list()
@@ -1181,6 +1186,9 @@
 
 # In case we want to give access to non-admin users in the future
 
+def havePermCreateCluster(self):
+	return isAdmin(self)
+
 def havePermAddStorage(self):
 	return isAdmin(self)
 
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2006/10/04 16:20:22	1.83
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2006/10/06 18:58:51	1.84
@@ -25,7 +25,7 @@
 #then only display chooser if the current user has
 #permissions on at least one. If the user is admin, show ALL clusters
 
-from homebase_adapters import nodeAuth, nodeUnauth, manageCluster, createClusterSystems
+from homebase_adapters import nodeAuth, nodeUnauth, manageCluster, createClusterSystems, havePermCreateCluster
 
 CLUSTER_FOLDER_PATH = '/luci/systems/cluster/'
 
@@ -105,6 +105,9 @@
 	messages = list()
 	requestResults = {}
 
+	if not havePermCreateCluster(self):
+		return (False, {'errors': ['You do not have sufficient rights to create a cluster.']})
+
 	try:
 	 	sessionData = request.SESSION.get('checkRet')
 	except:
@@ -119,8 +122,8 @@
 	except:
 		return (False, { 'errors': ['Unknown number of systems entered'], 'requestResults': requestResults })
 
-	if numStorage < 2:
-		return (False, { 'errors': ['A cluster must contain at least two nodes'], 'requestResults': requestResults })
+	if numStorage < 1:
+		return (False, { 'errors': ['A cluster must contain at least one node'], 'requestResults': requestResults })
 
 	ret = validateClusterNodes(request, sessionData, clusterName, numStorage)
 	errors.extend(ret[0])
@@ -128,22 +131,29 @@
 
 	try:
 		nodeList = cluster_properties['nodeList']
-		if len(nodeList) < 2:
+		if len(nodeList) < 1:
+			raise
+	except:
+		errors.append('A cluster must contain at least one node')
+
+	try:
+		cluster_os = nodeList[0]['os']
+		if not cluster_os:
+			raise
+		if len(filter(lambda x: x != cluster_os, nodeList[1:])) > 0:
 			raise
+	except KeyError, e:
+		errors.append('Unable to identify the operating system running on the first cluster node.')
+		cluster_properties['isComplete'] = False
 	except:
-		errors.append('A cluster must contain at least two nodes')
+		errors.append('Cluster nodes must be running compatible operating systems.')
+		cluster_properties['isComplete'] = False
 
 	if cluster_properties['isComplete'] != True:
 		nodeUnauth(nodeList)
 		return (False, {'errors': errors, 'requestResults':cluster_properties })
 
 	if cluster_properties['isComplete'] == True:
-		from ricci_communicator import RicciCommunicator
-		rc = RicciCommunicator(nodeList[0]['ricci_host'])
-		os_str = resolveOSType(rc.os())
-		if os_str == None:
-			os_str = "rhel5"  #Backup plan in case all is almost lost...
-
 		batchNode = createClusterBatch(os_str, clusterName, clusterName, map(lambda x: x['ricci_host'], nodeList), True, False, False)
 		if not batchNode:
 			nodeUnauth(nodeList)
@@ -298,23 +308,23 @@
 		else:
 			mcast_val = 0
 	except KeyError, e:
-		return (False, {'errors': 'An invalid multicast selection was made.'})
+		return (False, {'errors': ['An invalid multicast selection was made.']})
 
 	if not mcast_val:
-		return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+		return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 	try:
 		addr_str = form['mcast_addr'].strip()
 		socket.inet_pton(socket.AF_INET, addr_str)
 	except KeyError, e:
-		return (False, {'errors': 'No multicast address was given'})
+		return (False, {'errors': ['No multicast address was given']})
 	except socket.error, e:
 		try:
 			socket.inet_pton(socket.AF_INET6, addr_str)
 		except socket.error, e6:
-			return (False, {'errors': 'An invalid multicast address was given: ' + e})
+			return (False, {'errors': ['An invalid multicast address was given: ' + e]})
 
-	return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+	return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 def validateQDiskConfig(self, form):
 	errors = list()
@@ -328,10 +338,10 @@
 		else:
 			qdisk_val = 0
 	except KeyError, e:
-		return (False, {'errors': 'An invalid quorum partition selection was made.'})
+		return (False, {'errors': ['An invalid quorum partition selection was made.']})
 
 	if not qdisk_val:
-		return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+		return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 	try:
 		interval = int(form['interval'])
@@ -436,7 +446,7 @@
 
 	if len(errors) > 0:
 		return (False, {'errors': errors })
-	return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+	return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 def validateGeneralConfig(self, form):
 	errors = list()
@@ -460,7 +470,7 @@
 	if len(errors) > 0:
 		return (False, {'errors': errors})
 
-	return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+	return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 def validateFenceConfig(self, form):
 	errors = list()
@@ -486,7 +496,7 @@
 	if len(errors) > 0:
 		return (False, {'errors': errors })
 
-	return (True, {'messages': 'Changes accepted. - FILL ME IN'})
+	return (True, {'messages': ['Changes accepted. - FILL ME IN']})
 
 configFormValidators = {
 	'general': validateGeneralConfig,
@@ -500,11 +510,11 @@
 	messages = list()
 
 	if not 'form' in request:
-		return (False, {'errors': 'No form was submitted.' })
+		return (False, {'errors': ['No form was submitted.']})
 	if not 'configtype' in request.form:
-		return (False, {'errors': 'No configuration type was submitted.' })
+		return (False, {'errors': ['No configuration type was submitted.']})
 	if not request.form['configtype'] in configFormValidators:
-		return (False, {'errors': 'An invalid configuration type was submitted.' })
+		return (False, {'errors': ['An invalid configuration type was submitted.']})
 
 	val = configFormValidators[request.form['configtype']]
 	ret = val(self, request.form)
@@ -588,15 +598,17 @@
   else:
     cldata['currentItem'] = False
 
-  cladd = {}
-  cladd['Title'] = "Create a New Cluster"
-  cladd['cfg_type'] = "clusteradd"
-  cladd['absolute_url'] = url + "?pagetype=" + CLUSTER_ADD
-  cladd['Description'] = "Create a Cluster"
-  if pagetype == CLUSTER_ADD:
-    cladd['currentItem'] = True
-  else:
-    cladd['currentItem'] = False
+
+  if havePermCreateCluster(self):
+    cladd = {}
+    cladd['Title'] = "Create a New Cluster"
+    cladd['cfg_type'] = "clusteradd"
+    cladd['absolute_url'] = url + "?pagetype=" + CLUSTER_ADD
+    cladd['Description'] = "Create a Cluster"
+    if pagetype == CLUSTER_ADD:
+      cladd['currentItem'] = True
+    else:
+      cladd['currentItem'] = False
 
   clcfg = {}
   clcfg['Title'] = "Configure"
@@ -2692,21 +2704,21 @@
 
 def addResource(self, request, ragent):
 	if not request.form:
-		return (False, {'errors': 'No form was submitted.'})
+		return (False, {'errors': ['No form was submitted.']})
 
 	try:
 		type = request.form['type'].strip()
 		if not type or not type in resourceAddHandler:
 			raise
 	except:
-		return (False, {'errors': 'Form type is missing.'})
+		return (False, {'errors': ['Form type is missing.']})
 
 	try:
 		resname = request.form['resourceName']
 	except KeyError, e:
 		# For IP, the IP address itself is the name.
 		if request.form['type'] != 'ip':
-			return (False, {'errors': 'No resource name was given.'})
+			return (False, {'errors': ['No resource name was given.']})
 
 	res = resourceAddHandler[type](request)
 	modelb = request.SESSION.get('model')




More information about the Cluster-devel mailing list