[Cluster-devel] conga/luci cluster/form-chooser cluster/form-m ...

rmccabe at sourceware.org rmccabe at sourceware.org
Fri Feb 23 22:07:47 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe at sourceware.org	2007-02-23 22:07:45

Modified files:
	luci/cluster   : form-chooser form-macros 
	luci/homebase  : luci_homebase.css 
	luci/site/luci/Extensions: cluster_adapters.py 
	                           conga_constants.py ricci_bridge.py 
Added files:
	luci/cluster   : validate_sys_svc.js 
	luci/plone-custom: conga_ajax.js svc_reload.png 
	                   svc_reload_active.png svc_reload_disabled.png 
	                   svc_start.png svc_start_active.png 
	                   svc_start_disabled.png svc_stop.png 
	                   svc_stop_active.png svc_stop_disabled.png 
	luci/site/luci/Extensions: system_adapters.py 

Log message:
	- System service management interface (chkconfig / service start/stop/restart)

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_sys_svc.js.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.16&r2=1.17
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.192&r2=1.193
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/homebase/luci_homebase.css.diff?cvsroot=cluster&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/conga_ajax.js.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_reload_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_start_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop_active.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/svc_stop_disabled.png.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/system_adapters.py.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.243&r2=1.244
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.36&r2=1.37
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_bridge.py.diff?cvsroot=cluster&r1=1.58&r2=1.59

/cvs/cluster/conga/luci/cluster/validate_sys_svc.js,v  -->  standard output
revision 1.1
--- conga/luci/cluster/validate_sys_svc.js
+++ -	2007-02-23 22:07:45.984856000 +0000
@@ -0,0 +1,22 @@
+function svc_callback() {
+	if (xmlHttp_object.readyState == 4) {
+		if (xmlHttp_object.status == 200) {
+			var response = xmlHttp_object.responseXML;
+			if (response) {
+				req_status = response.getAttribute('success');
+				req_op = response.getAttribute('operation');
+				req_svc = response.getAttribute('service');
+				req_msg = response.getAttribute('message');
+				//alert(req_msg + ' / ' + req_status + ' / ' + req_op + ' / ' + req_svc);
+			} else {
+				alert(xmlHttp_object.responseText);
+			}
+		} else {
+			//alert('Error retrieving data from server: ' + xmlHttp_object.status);
+		}
+	}
+}
+
+function update_sys_svc(url) {
+	initiate_async_get(url, svc_callback);
+}
--- conga/luci/cluster/form-chooser	2007/02/01 20:27:33	1.16
+++ conga/luci/cluster/form-chooser	2007/02/23 22:07:45	1.17
@@ -149,11 +149,15 @@
     <span tal:omit-tag="" tal:condition="python: ptype == '55'">
      <div metal:use-macro="here/form-macros/macros/fencedevprocess-form"/>
     </span>
-
     <span tal:omit-tag="" tal:condition="python: ptype == '80'">
      <div metal:use-macro="here/form-macros/macros/conf_editor-form"/>
     </span>
-
+    <span tal:omit-tag="" tal:condition="python: ptype == '90'">
+     <div metal:use-macro="here/form-macros/macros/system-svc-form"/>
+    </span>
+    <span tal:omit-tag="" tal:condition="python: ptype == '91'">
+     <div metal:use-macro="here/form-macros/macros/system-svc-update-form"/>
+    </span>
    </span>
   </metal:choose-form>
   </body>
--- conga/luci/cluster/form-macros	2007/02/20 23:06:59	1.192
+++ conga/luci/cluster/form-macros	2007/02/23 22:07:45	1.193
@@ -5022,10 +5022,110 @@
 	</div>
 </div>
 
+
 <div metal:define-macro="fencedevprocess-form">
 	<h2>Fence Device Process Form</h2>
 </div>
 
+<div metal:define-macro="system-svc-form">
+	<script type="text/javascript"
+		src="conga_ajax.js">
+	</script>
+	<script type="text/javascript"
+		src="/luci/cluster/validate_sys_svc.js">
+	</script>
+	<h2>Configure System Services</h2>
+
+	<form name="svcform" method="post" action="">
+
+	<input type="hidden" name="pagetype"
+		tal:attributes="value request/pagetype | nothing" />
+
+	<input type="hidden" name="systemname"
+		tal:attributes="value request/systemname | nothing" />
+
+	<table class="systemsTable"
+		tal:define="svcinfo python:'systemname' in request and here.get_sys_svc_list(request, request['systemname']) or []">
+		<tr class="systemsTable">
+			<th class="systemsTable">Name</th>
+			<th class="systemsTable">State</th>
+			<th class="systemsTable">Enabled at boot</th>
+			<th></th>
+		</tr>
+
+		<tr tal:repeat="s svcinfo">
+			<td class="systemsTable">
+				<span tal:content="s/name |string:[unknown]"
+					tal:attributes="title s/desc | nothing" />
+			</td>
+
+			<td class="systemsTable">
+				<span
+					tal:content="s/state |string:[unknown]"
+					tal:attributes="id python: '__STATUS__:' + s['name']" />
+			</td>
+
+			<td class="systemsTable">
+				<input type="checkbox"
+					tal:attributes="
+						name s/name;
+						id s/name;
+						checked python: s['enabled'] and 'checked' or ''"
+				/>
+			</td>
+
+			<td class="systemsTable"
+				tal:define="
+					restart_disabled python:not s['running'] and 'disabled' or '';
+					start_disabled python:s['running'] and 'disabled' or '';
+					stop_disabled python:not s['running'] and 'disabled' or ''">
+
+				<input type="button"
+					title="start this service"
+					class="svc_control svc_control_start"
+					onfocus="if (this.blur) this.blur()"
+					tal:attributes="
+						onclick python: 'update_sys_svc(\'' + s['starturl'] + '\')';
+						id python: '__START__' + s['name'];
+						name python: '__START__' + s['name'];
+						disabled start_disabled" />
+
+				<input type="button"
+					title="restart this service"
+					class="svc_control svc_control_restart"
+					onfocus="if (this.blur) this.blur()"
+					tal:attributes="
+						onclick python: 'update_sys_svc(\'' + s['restarturl'] + '\')';
+						id python: '__RESTART__' + s['name'];
+						name python: '__RESTART__' + s['name'];
+						disabled restart_disabled" />
+
+				<input type="button"
+					title="stop this service"
+					class="svc_control svc_control_stop"
+					onfocus="if (this.blur) this.blur()"
+					tal:attributes="
+						onclick python: 'update_sys_svc(\'' + s['stopurl'] + '\')';
+						id python: '__STOP__' + s['name'];
+						name python: '__STOP__' + s['name'];
+						disabled stop_disabled" />
+			</td>
+		</tr>
+		<tr class="systemsTable">
+			<td>
+				<div class="hbSubmit">
+					<input type="submit" value="Update" />
+				</div>
+			</td>
+		</tr>
+	</table>
+	</form>
+</div>
+
+<div metal:define-macro="system-svc-update-form">
+	<tal:block tal:define="ret python: here.validate_manage_svc(request)" />
+</div>
+
 <div metal:define-macro="conf_editor-form">
 	<h2>Edit cluster.conf</h2>
 	<form method="post"
--- conga/luci/homebase/luci_homebase.css	2007/02/08 05:05:22	1.39
+++ conga/luci/homebase/luci_homebase.css	2007/02/23 22:07:45	1.40
@@ -8,6 +8,60 @@
 	font-size: 12px;
 }
 
+input[type=image] {
+	border: 0;
+	background: transparent;
+	padding-left: +.3333em;
+	padding-right: +.3333em;
+}
+
+input[type=image]:disabled {
+	cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control {
+	color: transparent ! important;
+	border: none ! important;
+	outline: hidden ! important;
+	background-color: transparent ! important;
+	background-repeat: no-repeat ! important;
+	cursor: pointer;
+}
+
+.svc_control_start {
+	background-image: url(svc_start.png);
+}
+
+input.svc_control_start:hover, input.svc_control_start:active {
+	background-image: url(svc_start_active.png) ! important;
+}
+input.svc_control_start:disabled {
+	background-image: url(svc_start_disabled.png) ! important;
+	cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control_restart {
+	background-image: url(svc_reload.png);
+}
+input.svc_control_restart:hover, input.svc_control_restart:active {
+	background-image: url(svc_reload_active.png) ! important;
+}
+input.svc_control_restart:disabled {
+	background-image: url(svc_reload_disabled.png) ! important;
+	cursor: url('cursor-disabled.png'), default;
+}
+
+input.svc_control_stop {
+	background-image: url(svc_stop.png);
+}
+input.svc_control_stop:hover, input.svc_control_stop:active {
+	background-image: url(svc_stop_active.png) ! important;
+}
+input.svc_control_stop:disabled {
+	background-image: url(svc_stop_disabled.png) ! important;
+	cursor: url('cursor-disabled.png'), default;
+}
+
 input[type=checkbox], input[type=radio] {
 	float: left ! important;
 	vertical-align: middle;
/cvs/cluster/conga/luci/plone-custom/conga_ajax.js,v  -->  standard output
revision 1.1
--- conga/luci/plone-custom/conga_ajax.js
+++ -	2007-02-23 22:07:46.355394000 +0000
@@ -0,0 +1,29 @@
+var xmlHttp_object = false;
+
+function initiate_async_get(url, callback_function) {
+	xmlHttp_object = false;
+
+	if (!xmlHttp_object && typeof XMLHttpRequest != 'undefined') {
+		try {
+			xmlHttp_object = new XMLHttpRequest();
+		} catch (e0) {
+			try {
+				xmlHttp_object = new ActiveXObject("Msxml2.XMLHTTP");
+			} catch (e) {
+				try {
+					xmlHttp_object = new ActiveXObject("Microsoft.XMLHTTP");
+				} catch (e2) {
+					xmlHttp_object = false;
+				}
+			}
+		}
+	}
+
+	if (xmlHttp_object) {
+		xmlHttp_object.open("GET", url, true);
+		xmlHttp_object.onreadystatechange = callback_function;
+		xmlHttp_object.send(null);
+	} else {
+		alert("Unable to communicate with the luci server.");
+	}
+}
/cvs/cluster/conga/luci/plone-custom/svc_reload.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_reload_active.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_reload_disabled.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_reload_disabled.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start_active.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_start_disabled.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_start_disabled.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop_active.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop_active.png and - differ
/cvs/cluster/conga/luci/plone-custom/svc_stop_disabled.png,v  -->  standard output
revision 1.1
Binary files /cvs/cluster/conga/luci/plone-custom/svc_stop_disabled.png and - differ
/cvs/cluster/conga/luci/site/luci/Extensions/system_adapters.py,v  -->  standard output
revision 1.1
--- conga/luci/site/luci/Extensions/system_adapters.py
+++ -	2007-02-23 22:07:47.286199000 +0000
@@ -0,0 +1,134 @@
+from ricci_communicator import RicciCommunicator
+from ricci_bridge import list_services, updateServices, svc_manage
+from LuciSyslog import LuciSyslog
+
+try: 
+	luci_log = LuciSyslog()
+except:
+	pass
+
+def get_sys_svc_list(self, request, hostname):
+	try:
+		rc = RicciCommunicator(hostname)
+		if not rc:
+			raise Exception, 'None'
+	except Exception, e:
+		luci_log.debug_verbose('GSSL0: %s: %s' % (hostname, str(e)))
+		return []
+
+	service_list = list_services(rc)
+	if not service_list:
+		return []
+
+	svc_ret = list()
+	for i in service_list:
+		s = {}
+		try:
+			name = str(i.getAttribute('name'))
+		except:
+			name = None
+		s['name'] = name
+
+		try:
+			desc = i.getAttribute('description')
+		except:
+			desc = None
+		s['desc'] = desc
+
+		try:
+			enabled = i.getAttribute('enabled').lower()
+			if enabled == 'true':
+				s['enabled'] = True
+			else:
+				raise Exception, 'not enabled'
+		except:
+			s['enabled'] = False
+
+		try:
+			running = i.getAttribute('running').lower()
+			if running == 'true':
+				s['running'] = True
+				s['state'] = 'Running'
+			else:
+				raise Exception, 'not running'
+		except Exception, e:
+			s['running'] = False
+			s['state'] = 'Stopped'
+
+		s['starturl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=start' % (request['URL'], s['name'], hostname)
+		s['stopurl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=stop' % (request['URL'], s['name'], hostname)
+		s['restarturl'] = '%s?pagetype=91&svcname=%s&systemname=%s&operation=restart' % (request['URL'], s['name'], hostname)
+		svc_ret.append(s)
+
+	return svc_ret
+
+def validate_svc_update(self, request):
+	try:
+		form = request.form
+		hostname = form['systemname'].strip()
+		if not hostname:
+			raise Exception, 'blank'
+	except Exception, e:
+		return (False, {'errors': [ 'No system name was given.' ]})
+
+	try:
+		rc = RicciCommunicator(hostname)
+		if not rc:
+			raise Exception, 'unknown error'
+	except Exception, e:
+		luci_log.debug_verbose('VSU0: %s: %s' % (hostname, str(e)))
+		return (False, {'errors': [ 'Unable to connect to the ricci agent on %s: %s' % (hostname, str(e)) ]})
+
+	sys_svc_list = list()
+	sys_svc_hash = dict()
+
+	try:
+		for i in list_services(rc):
+			svc_name = str(i.getAttribute('name'))
+			sys_svc_hash[svc_name] = i
+			sys_svc_list.append(svc_name)
+	except Exception, e:
+		luci_log.debug_verbose('VSU1: %s: %s' % (hostname, str(e)))
+		return (False, {'errors': [ 'Unable to retrieve the list of services from %s' % hostname ]})
+
+	try:
+		del form['pagetype']
+		del form['systemname']
+	except:
+		pass
+
+	disable_list = filter(lambda x: not form.has_key(x) and sys_svc_hash[x].getAttribute('enabled').lower() == 'true', sys_svc_list)
+	enable_list = filter(lambda x: form.has_key(x) and sys_svc_hash[x].getAttribute('enabled').lower() != 'true', sys_svc_list)
+
+	updateServices(rc, enable_list, disable_list)
+	request.RESPONSE.redirect(request['URL'] + '?pagetype=90&systemname=' + hostname)
+
+def validate_manage_svc(self, request):
+	try:
+		hostname = request['systemname'].strip()
+	except:
+		return None
+
+	servicename = None
+	op = None
+	try:
+		servicename = request['svcname'].strip()
+		op = request['operation'].strip()
+	except:
+		pass
+
+	try:
+		rc = RicciCommunicator(hostname)
+		if not rc:
+			raise Exception, 'none'
+	except Exception, e:
+		return None
+
+	ret = None
+	try:
+		ret = svc_manage(rc, hostname, servicename, op)
+		luci_log.debug_verbose('VMC0: returning %s' % str(ret.toxml()))
+	except:
+		pass
+
+	return ret
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2007/02/22 20:52:51	1.243
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2007/02/23 22:07:45	1.244
@@ -41,6 +41,7 @@
 from GeneralError import GeneralError
 from homebase_adapters import manageCluster, createClusterSystems, havePermCreateCluster, setNodeFlag, delNodeFlag, userAuthenticated, getStorageNode, getClusterNode, delCluster, parseHostForm
 from LuciSyslog import LuciSyslog
+from system_adapters import validate_svc_update
 
 #Policy for showing the cluster chooser menu:
 #1) If there are no clusters in the ManagedClusterSystems
@@ -2453,7 +2454,8 @@
 	54: validateFenceEdit,
 	55: validateDaemonProperties,
 	57: deleteFenceDevice,
-	58: validateNodeFenceConfig
+	58: validateNodeFenceConfig,
+	90: validate_svc_update
 }
 
 def validatePost(self, request):
--- conga/luci/site/luci/Extensions/conga_constants.py	2007/02/01 20:49:08	1.36
+++ conga/luci/site/luci/Extensions/conga_constants.py	2007/02/23 22:07:45	1.37
@@ -48,6 +48,8 @@
 FENCEDEV_NODE_CONFIG = '58'
 
 CONF_EDITOR = '80'
+SYS_SERVICE_MANAGE = '90'
+SYS_SERVICE_UPDATE = '91'
 
 #Cluster tasks
 CLUSTER_STOP = '1000'
--- conga/luci/site/luci/Extensions/ricci_bridge.py	2007/02/22 20:52:51	1.58
+++ conga/luci/site/luci/Extensions/ricci_bridge.py	2007/02/23 22:07:45	1.59
@@ -486,6 +486,70 @@
 	ricci_xml = rc.batch_run(batch_str)
 	return batchAttemptResult(ricci_xml)
 
+def svc_manage(rc, hostname, servicename, op):
+	svc_func = None
+
+	doc = minidom.Document()
+	elem = doc.createElement('result')
+
+	if not servicename:
+		elem.setAttribute('service', 'No service name was specified.')
+		elem.setAttribute('message', 'No service name was specified.')
+		elem.setAttribute('success', '0')
+
+	if not op:
+		elem.setAttribute('operation', 'No operation was specified.')
+		elem.setAttribute('message', 'No operation was specified.')
+		elem.setAttribute('success', '0')
+
+	if not servicename or not op:
+		doc.appendChild(elem)
+		return doc
+
+	elem.setAttribute('service', servicename)
+	elem.setAttribute('operation', op)
+	elem.setAttribute('hostname', hostname)
+
+	try:
+		op = op.strip().lower()
+		if op == 'restart' or op == 'start' or op == 'stop':
+			svc_func = op
+		else:
+			raise Exception, op
+	except Exception, e:
+		elem.setAttribute('success', '0');
+		elem.setAttribute('message', 'Unknown operation')
+		doc.appendChild(elem)
+		return doc
+
+	batch_str = '<module name="service"><request API_version="1.0"><function_call name="%s"><var mutable="false" name="services" type="list_xml"><service name="%s"/></var></function_call></request></module>' % (svc_func, servicename)
+		
+	ricci_xml = rc.batch_run(batch_str, async=False)
+	if not ricci_xml or not ricci_xml.firstChild:
+		luci_log.debug_verbose('SVCM0: None returned')
+		elem.setAttribute('success', '0')
+		elem.setAttribute('message', 'operation failed')
+		doc.appendChild(elem)
+		return doc
+
+	elem.setAttribute('success', '0')
+	elem.setAttribute('message', str(ricci_xml.toxml()))
+	doc.appendChild(elem)
+	return doc
+
+def list_services(rc):
+	batch_str = '<module name="service"><request API_version="1.0"><function_call name="list"><var mutable="false" name="description" type="boolean" value="true"/></function_call></request></module>'
+	ricci_xml = rc.batch_run(batch_str, async=False)
+	if not ricci_xml or not ricci_xml.firstChild:
+		luci_log.debug_verbose('LS0: None returned')
+		return None
+	try:
+		service_tags = ricci_xml.getElementsByTagName('service')
+		return service_tags
+	except Exception, e:
+		luci_log.debug_verbose('LS1: %s' % str(e))
+	return None
+
 def nodeIsVirtual(rc):
 	batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="virt_guest"/></request></module>'
 




More information about the Cluster-devel mailing list