[Cluster-devel] conga luci/cluster/fence_device.js luci/cluste ...

rmccabe at sourceware.org rmccabe at sourceware.org
Wed Aug 8 21:00:14 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	rmccabe at sourceware.org	2007-08-08 21:00:08

Modified files:
	luci/cluster   : fence_device.js form-chooser form-macros 
	                 resource_form_handlers.js 
	                 validate_config_fence.js 
	                 validate_config_general.js 
	                 validate_config_gulm.js 
	                 validate_config_multicast.js 
	                 validate_config_qdisk.js 
	                 validate_create_gulm.js validate_fdom.js 
	                 validate_fence.js validate_sys_svc.js 
	luci/plone-custom: conga_ajax.js 
	luci/site/luci/Extensions: HelperFunctions.py LuciClusterInfo.py 
	                           LuciZope.py LuciZopeExternal.py 
	                           RicciQueries.py cluster_adapters.py 
	                           conga_constants.py 
	                           homebase_adapters.py 
	luci/site/luci/Extensions/ClusterModel: Device.py 
	make           : version.in 
Added files:
	luci/cluster   : validate_xvm_key.js 
	luci/site/luci/Extensions: LuciZopeAsync.py 

Log message:
	support for distributing fence_xvm keys

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_xvm_key.js.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/fence_device.js.diff?cvsroot=cluster&r1=1.13&r2=1.14
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-chooser.diff?cvsroot=cluster&r1=1.18&r2=1.19
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/form-macros.diff?cvsroot=cluster&r1=1.205&r2=1.206
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/resource_form_handlers.js.diff?cvsroot=cluster&r1=1.38&r2=1.39
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_fence.js.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_general.js.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_gulm.js.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_multicast.js.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_config_qdisk.js.diff?cvsroot=cluster&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_create_gulm.js.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_fdom.js.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_fence.js.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/validate_sys_svc.js.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/plone-custom/conga_ajax.js.diff?cvsroot=cluster&r1=1.1&r2=1.2
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeAsync.py.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/HelperFunctions.py.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciClusterInfo.py.diff?cvsroot=cluster&r1=1.9&r2=1.10
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZope.py.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciZopeExternal.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.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.264&r2=1.265
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/conga_constants.py.diff?cvsroot=cluster&r1=1.42&r2=1.43
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/homebase_adapters.py.diff?cvsroot=cluster&r1=1.52&r2=1.53
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ClusterModel/Device.py.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/make/version.in.diff?cvsroot=cluster&r1=1.32&r2=1.33

/cvs/cluster/conga/luci/cluster/validate_xvm_key.js,v  -->  standard output
revision 1.1
--- conga/luci/cluster/validate_xvm_key.js
+++ -	2007-08-08 21:00:08.858061000 +0000
@@ -0,0 +1,119 @@
+/*
+** Copyright (C) 2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
+function get_cluster_members(host_list) {
+	var url = '/luci/cluster?pagetype=1000';
+	var node_num = 0;
+
+	var hclu_elem = document.getElementById('host_cluster_name');
+	if (hclu_elem) {
+		++node_num;
+		url += '&node' + node_num + '=' + hclu_elem.value;
+	}
+	var vclu_elem = document.getElementById('virt_cluster_name');
+	if (vclu_elem) {
+		++node_num;
+		url += '&node' + node_num + '=' + vclu_elem.value;
+	}
+    initiate_async_get(url, cluster_member_callback);
+}
+
+function cluster_member_callback() {
+	return check_ajax_xml(xmlHttp_object, cluster_member_check);
+}
+
+function validate_xvm_dist_form(form) {
+	return form.submit();
+}
+
+function cluster_member_check(ret_status, obj) {
+	if (ret_status === null) {
+		/* Not ready */
+		return;
+	}
+
+	if (ret_status !== true) {
+		/* A communication error occurred. */
+		alert(obj);
+		return;
+	}
+
+	var err = get_ricci_response_status(obj.responseXML);
+	if (err !== null && err.length > 0) {
+		alert(err.join('\n'));
+		return;
+	}
+
+	obj = obj.responseXML;
+	var clusters = [];
+	var dict_tags = obj.firstChild.getElementsByTagName('dict');
+	for (var i = 0 ; i < dict_tags.length ; i++) {
+		try {
+			var cnode_names = [];
+			var tag_name = dict_tags[i].getAttribute('name');
+			var cnodes = dict_tags[i].getElementsByTagName('clusternode');
+
+			for (var j = 0 ; j < cnodes.length ; j++) {
+				cnode_names.push(cnodes[j].getAttribute('value'));
+			}
+			clusters.push([ tag_name, cnode_names ]);
+		} catch (e) {
+			continue;
+		}
+	}
+
+	var form_elem = document.getElementById('fence_config_form');
+	var xvm_submit_elem = document.getElementById('fence_config_submit');
+	var xvm_div_elem = document.getElementById('fence_xvm_hosts');
+	var xvm_hidden_elem = document.getElementById('fence_xvm_config');
+
+	if (!form_elem || !xvm_submit_elem || !xvm_div_elem || !xvm_hidden_elem) {
+		alert('Server error: required form elements are missing.');
+		return;
+	}
+
+	for (var i = 0 ; i < clusters.length ; i++) {
+		var cnode_list = clusters[i][1];
+
+		var div = document.createElement('div');
+		var p = document.createElement('p');
+		var span = document.createElement('strong');
+		var ul = document.createElement('ul');
+
+		p.className = 'cluster';
+		span.className = 'cluster';
+		span.textContent = 'Cluster: ' + clusters[i][0];
+
+		p.appendChild(span);
+		div.appendChild(p);
+
+		for (var j = 0 ; j < cnode_list.length ; j++) {
+			var li = document.createElement('li');
+			var input = document.createElement('input');
+			var lispan = document.createElement('span');
+			input.type = 'checkbox';
+			input.name = '__NODE_HOSTNAME__';
+			input.value = cnode_list[j];
+			input.checked = 'checked';
+			lispan.textContent = cnode_list[j];
+			li.appendChild(input);
+			li.appendChild(lispan);
+			ul.appendChild(li);
+		}
+		div.appendChild(ul);
+		xvm_div_elem.appendChild(div);
+	}
+
+	var fc_elem = document.getElementById('fence_xvm_init');
+	if (fc_elem) {
+		form_elem.pagetype.value = '60';
+		fc_elem.className = 'invisible';
+		xvm_hidden_elem.className = 'systemsTable';
+	}
+}
--- conga/luci/cluster/fence_device.js	2007/07/12 02:42:42	1.13
+++ conga/luci/cluster/fence_device.js	2007/08/08 21:00:06	1.14
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 var num_fences_level = [ 0, 0 ];
 var num_fence_instances = [];
 
--- conga/luci/cluster/form-chooser	2007/03/12 04:25:41	1.18
+++ conga/luci/cluster/form-chooser	2007/08/08 21:00:06	1.19
@@ -161,6 +161,9 @@
     <span tal:omit-tag="" tal:condition="python: ptype == '91'">
      <div metal:use-macro="here/form-macros/macros/system-svc-update-form"/>
     </span>
+    <tal:block tal:condition="python: ptype == '1000'">
+     <div metal:use-macro="here/form-macros/macros/get-cluster-members-form"/>
+	</tal:block>
    </span>
   </metal:choose-form>
   </body>
--- conga/luci/cluster/form-macros	2007/07/27 16:43:46	1.205
+++ conga/luci/cluster/form-macros	2007/08/08 21:00:06	1.206
@@ -531,6 +531,12 @@
 	<script type="text/javascript">
 		set_page_title('Luci — cluster — Configure cluster properties');
 	</script>
+	<script type="text/javascript"
+		src="conga_ajax.js">
+	</script>
+	<script type="text/javascript"
+		src="validate_xvm_key.js">
+	</script>
 
 	<tal:block tal:define="
 		global ricci_agent ri_agent | python: here.getRicciAgentForCluster(request)" />
@@ -917,7 +923,7 @@
 	</div>
 
 	<div id="configTabContent" tal:condition="python: configTabNum == 2">
-		<form name="fencedaemon" method="post" action="">
+		<form name="fencedaemon" method="post" id="fence_config_form" action="">
 			<input type="hidden" name="configtype" value="fence" />
 			<input type="hidden" name="pagetype"
 				tal:attributes="value request/pagetype | request/form/pagetype"
@@ -967,6 +973,68 @@
 							tal:attributes="checked python: ('fence_xvmd' in clusterinfo and clusterinfo['fence_xvmd']) and 'checked' or ''" />
 					</td>
 				</tr>
+				<tr class="systemsTable">
+					<td class="systemsTable" colspan="2">
+						<div class="systemsTableTop"> </div>
+						<strong>XVM fence daemon key distribution</strong>
+					</td>
+				</tr>
+
+				<tr id="fence_xvm_config" class="invisible">
+					<td class="systemsTable" colspan="2" id="fence_xvm_config">
+						<table class="systemsTable">
+							<tr class="systemsTable">
+								<td class="systemsTable">
+									<div id="fence_xvm_hosts" />
+								</td>
+							</tr>
+							<tr class="systemsTable">
+								<td class="systemsTable">
+									<input type="button" name="distribute"
+										value="Create and distribute keys"
+										onclick="validate_xvm_dist_form(this.form)"
+									/>
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
+
+				<tr class="systemsTable" id="fence_xvm_init">
+					<td class="systemsTable" colspan="2">
+						<table class="systemsTable">
+							<tr class="systemsTable">
+								<td class="systemsTable">
+									Enter a node hostname from the host cluster
+								</td>
+								<td>
+									<input type="text" value=""
+										name="host_cluster_name"
+										id="host_cluster_name" />
+								</td>
+							</tr>
+							<tr class="systemsTable">
+								<td class="systemsTable">
+									Enter a node hostname from the hosted (virtual) cluster
+								</td>
+								<td>
+									<input type="text" value=""
+										name="virt_cluster_name"
+										id="virt_cluster_name" />
+								</td>
+							</tr>
+							<tr class="systemsTable">
+								<td class="systemsTable" colspan="2">
+									<input type="button"
+										name="Retrieve cluster nodes"
+										value="Retrieve cluster nodes"
+										onclick="get_cluster_members(this.form)"
+									/>
+								</td>
+							</tr>
+						</table>
+					</td>
+				</tr>
 			</tbody>
 
 			<tfoot class="systemsTable">
@@ -974,7 +1042,8 @@
 					<td class="systemsTable" colspan="2">
 						<div class="systemsTableEnd">
 							<input type="button" value="Apply"
-								onClick="validate_form(this.form);" />
+								id="fence_config_submit"
+								onClick="validate_form(this.form)" />
 						</div>
 					</td>
 				</tr>
@@ -5301,6 +5370,10 @@
 	</form>
 </div>
 
+<div metal:define-macro="get-cluster-members-form">
+	<tal:block tal:define="ret python: here.get_cluster_nodes_async(request)" />
+</div>
+
 <div metal:define-macro="system-svc-update-form">
 	<tal:block tal:define="ret python: here.validate_manage_svc(request)" />
 </div>
--- conga/luci/cluster/resource_form_handlers.js	2007/07/30 02:24:15	1.38
+++ conga/luci/cluster/resource_form_handlers.js	2007/08/08 21:00:06	1.39
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function swap_in_global_res(container_id, sel, replace, form) {
 	sel.id = null;
 	var container = document.getElementById(container_id);
--- conga/luci/cluster/validate_config_fence.js	2006/10/04 16:39:07	1.3
+++ conga/luci/cluster/validate_config_fence.js	2007/08/08 21:00:06	1.4
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function validate_form(form) {
 	var errors = new Array();
 
--- conga/luci/cluster/validate_config_general.js	2007/01/29 16:56:50	1.4
+++ conga/luci/cluster/validate_config_general.js	2007/08/08 21:00:06	1.5
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function validate_form(form) {
 	var errors = new Array();
 	var name = null;
--- conga/luci/cluster/validate_config_gulm.js	2007/02/01 23:48:51	1.3
+++ conga/luci/cluster/validate_config_gulm.js	2007/08/08 21:00:06	1.4
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function validate_form(form) {
 	var errors = new Array();
 	var lscount = 0;
--- conga/luci/cluster/validate_config_multicast.js	2006/10/04 17:24:58	1.3
+++ conga/luci/cluster/validate_config_multicast.js	2007/08/08 21:00:06	1.4
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 var prev_mcast_str = '';
 
 function disable_mcast(addrId) {
--- conga/luci/cluster/validate_config_qdisk.js	2007/07/12 02:42:42	1.7
+++ conga/luci/cluster/validate_config_qdisk.js	2007/08/08 21:00:06	1.8
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 var heuristic_names = [ ':hprog', ':hinterval', ':hscore', ':hdel' ];
 
 function clear_heuristic(form, heur_num) {
--- conga/luci/cluster/validate_create_gulm.js	2007/01/30 22:26:00	1.1
+++ conga/luci/cluster/validate_create_gulm.js	2007/08/08 21:00:06	1.2
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 var lockservers = new Array();
 
 function toggle_gulm(form, lock_type) {
--- conga/luci/cluster/validate_fdom.js	2007/02/08 03:42:58	1.3
+++ conga/luci/cluster/validate_fdom.js	2007/08/08 21:00:06	1.4
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function fdom_set_prioritized(form, state) {
 	var prilist = form.getElementsByTagName('input');
 	if (!prilist)
--- conga/luci/cluster/validate_fence.js	2007/07/27 16:43:47	1.11
+++ conga/luci/cluster/validate_fence.js	2007/08/08 21:00:06	1.12
@@ -1,3 +1,12 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 var fence_inst_validator = [];
 fence_inst_validator['apc'] = [ 'port', 'switch' ];
 fence_inst_validator['bladecenter'] = [ 'blade' ];
--- conga/luci/cluster/validate_sys_svc.js	2007/02/24 07:02:42	1.2
+++ conga/luci/cluster/validate_sys_svc.js	2007/08/08 21:00:06	1.3
@@ -1,48 +1,64 @@
+/*
+** Copyright (C) 2006-2007 Red Hat, Inc.
+**
+** This program is free software; you can redistribute
+** it and/or modify it under the terms of version 2 of the
+** GNU General Public License as published by the
+** Free Software Foundation.
+*/
+
 function svc_callback() {
-	if (xmlHttp_object.readyState == 4) {
-		if (xmlHttp_object.status == 200) {
-			var response = xmlHttp_object.responseXML;
-			if (response) {
-				var result = response.getElementsByTagName('result')[0];
-				var req_status = result.getAttribute('success');
-				var req_op = result.getAttribute('operation');
-				var req_svc = result.getAttribute('service');
-				var req_msg = result.getAttribute('message');
-
-				if (req_status != '0') {
-					var op_str = null;
-					if (req_op == 'stop')
-						op_str = 'stopped';
-					else
-						op_str = req_op + 'ed';
-
-					alert('Service ' + req_svc + ' was successfully ' + op_str);
-
-					var status_elem = document.getElementById('__STATUS__' + req_svc);
-					var start_elem = document.getElementById('__START__' + req_svc);
-					var restart_elem = document.getElementById('__RESTART__' + req_svc);
-					var stop_elem = document.getElementById('__STOP__' + req_svc);
-
-					if (req_op == 'stop') {
-						stop_elem.disabled = 'disabled';
-						restart_elem.disabled = 'disabled';
-						start_elem.disabled = '';
-						status_elem.innerHTML = 'Stopped';
-					} else {
-						stop_elem.disabled = '';
-						restart_elem.disabled = '';
-						start_elem.disabled = 'disabled';
-						status_elem.innerHTML = 'Running';
-					}
-				} else {
-					alert('An error occurred while attempting to ' + req_op + ' service ' + req_svc + ': ' + req_msg);
-				}
-			} else {
-				alert('Error retrieving data from server');
-			}
+	return check_ajax_xml(xmlHttp_object, svc_callback_check));
+}
+
+function svc_callback_check(ret_status, obj) {
+	if (ret_status === null) {
+		/* Not ready */
+		return;
+	}
+
+	if (ret_status !== true) {
+		/* A communication error occurred. */
+		alert(obj);
+		return;
+	}
+
+	/* The request succeeded, check for operation success. */
+	var response = obj;
+	var result = response.getElementsByTagName('result')[0];
+	var req_status = result.getAttribute('success');
+	var req_op = result.getAttribute('operation');
+	var req_svc = result.getAttribute('service');
+	var req_msg = result.getAttribute('message');
+
+	if (req_status != '0') {
+		var op_str = null;
+		if (req_op == 'stop') {
+			op_str = 'stopped';
+		} else {
+			op_str = req_op + 'ed';
+		}
+
+		alert('Service ' + req_svc + ' was successfully ' + op_str);
+
+		var status_elem = document.getElementById('__STATUS__' + req_svc);
+		var start_elem = document.getElementById('__START__' + req_svc);
+		var restart_elem = document.getElementById('__RESTART__' + req_svc);
+		var stop_elem = document.getElementById('__STOP__' + req_svc);
+
+		if (req_op == 'stop') {
+			stop_elem.disabled = 'disabled';
+			restart_elem.disabled = 'disabled';
+			start_elem.disabled = '';
+			status_elem.innerHTML = 'Stopped';
 		} else {
-			alert('Error retrieving data from server: ' + xmlHttp_object.status);
+			stop_elem.disabled = '';
+			restart_elem.disabled = '';
+			start_elem.disabled = 'disabled';
+			status_elem.innerHTML = 'Running';
 		}
+	} else {
+		alert('An error occurred while attempting to ' + req_op + ' service ' + req_svc + ': ' + req_msg);
 	}
 }
 
--- conga/luci/plone-custom/conga_ajax.js	2007/02/23 22:07:45	1.1
+++ conga/luci/plone-custom/conga_ajax.js	2007/08/08 21:00:07	1.2
@@ -27,3 +27,61 @@
 		alert("Unable to communicate with the luci server.");
 	}
 }
+
+function get_ajax_msgs(obj, tag_name) {
+	try {
+		var msgs = []
+		var msg_list = obj.getElementsByTagName(tag_name);
+		for (var i = 0 ; i < msg_list.length ; i++) {
+			var msg_txt = msg_list[i].getAttribute('value');
+			msgs.push(msg_txt);
+		}
+		return msgs;
+	} catch (e) {
+		return null;
+	}
+	return null;
+}
+
+function check_ajax_xml(xmlobj, handler_func) {
+	if (xmlobj.readyState != 4) {
+		return null;
+	}
+
+	if (xmlobj.status == 200) {
+		if (xmlobj.responseXML) {
+			return handler_func(true, xmlobj);
+		} else {
+			return handler_func(false, 'Error retrieving data from server');
+		}
+	} else {
+		return handler_func(false, 'Error retrieving data from server: ' + xmlobj.status);
+	}
+}
+
+function get_ricci_response_status(obj) {
+	if (!obj) {
+		return [ 'No response from server' ]
+	}
+
+	var rlist = obj.getElementsByTagName('result');
+	for (var i = 0 ; i < rlist.length ; i++) {
+		var elem_name = null;
+
+		try {
+			elem_name = rlist[i].getAttribute('name');
+			if (elem_name != 'success') {
+				continue;
+			} else {
+				var result = rlist[i].getAttribute('value');
+				if (result == 'true') {
+					return null;
+				}
+				break;
+			}
+		} catch (e) {
+			continue;
+		}
+	}
+	return get_ajax_msgs(obj, 'errors');
+}
/cvs/cluster/conga/luci/site/luci/Extensions/LuciZopeAsync.py,v  -->  standard output
revision 1.1
--- conga/luci/site/luci/Extensions/LuciZopeAsync.py
+++ -	2007-08-08 21:00:12.770994000 +0000
@@ -0,0 +1,182 @@
+# Copyright (C) 2007 Red Hat, Inc.
+#
+# This program is free software; you can redistribute
+# it and/or modify it under the terms of version 2 of the
+# GNU General Public License as published by the
+# Free Software Foundation.
+
+from xml.dom import minidom
+
+from LuciSyslog import get_logger
+from LuciZope import GetReqVars
+from ricci_communicator import RicciCommunicator
+from conga_constants import LUCI_DEBUG_MODE
+
+luci_log = get_logger()
+
+def write_xml_resp(request, xml_obj):
+	request.RESPONSE.setHeader('Content-Type', 'text/xml; charset=UTF-8')
+	request.RESPONSE.setHeader('Cache-Control', 'no-cache, no-store, private')
+	request.RESPONSE.write(str(xml_obj.toprettyxml()))
+
+def result_to_xml(result):
+	import types
+
+	numeric_types = [
+		types.IntType, types.BooleanType, types.LongType, types.FloatType
+	]
+
+	root = minidom.Document()
+
+	def pyobj_to_xml(element_name, element, parent_node):
+		if type(element) is types.DictType:
+			if len(element) > 0:
+				xml_elem = root.createElement('dict')
+				xml_elem.setAttribute('name', str(element_name))
+
+				for i in element.iterkeys():
+					pyobj_to_xml(i, element[i], xml_elem)
+			else:
+				xml_elem = None
+		elif type(element) in [ types.ListType, types.TupleType ]:
+			if len(element) > 0:
+				xml_elem = root.createElement('list')
+				xml_elem.setAttribute('name', str(element_name))
+				for i in element:
+					pyobj_to_xml(element_name, i, xml_elem)
+			else:
+				xml_elem = None
+		else:
+			cur_tagname = None
+			try:
+				if parent_node.tagName == 'list':
+					cur_tagname = parent_node.getAttribute('name')
+			except:
+				cur_tagname = None
+
+			if not cur_tagname:
+				xml_elem = root.createElement('var')
+			else:
+				xml_elem = root.createElement(cur_tagname)
+
+			if type(element) in types.StringTypes:
+				cur_type = 'str'
+			elif type(element) in numeric_types:
+				cur_type = 'num'
+			else:
+				cur_type = None
+
+			if cur_type:
+				try:
+					if parent_node.tagName == 'dict':
+						xml_elem.setAttribute('name', str(element_name))
+				except:
+					pass
+
+				xml_elem.setAttribute('type', cur_type)
+				xml_elem.setAttribute('value', str(element))
+			else:
+				xml_elem = None
+
+		if xml_elem is not None:
+			parent_node.appendChild(xml_elem)
+
+	pyobj_to_xml('result', result[1], root)
+	res_elem = root.createElement('result')
+	res_elem.setAttribute('name', 'success')
+	res_elem.setAttribute('value', str(result[0]).lower())
+	root.firstChild.appendChild(res_elem)
+	return root
+
+def write_err_async(request, err_msg):
+	xml_obj = result_to_xml((False, { 'errors': err_msg }))
+	write_xml_resp(request, xml_obj)
+
+def get_cluster_nodes_async(self, request):
+	from LuciClusterInfo import getClusterConfNodes
+	from RicciQueries import getClusterConf
+
+	fvars = GetReqVars(request, [ 'QUERY_STRING' ])
+	if fvars['QUERY_STRING'] is None:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('GCNA: No query string was given')
+		write_err_async(request, 'No node names were given')
+		return None
+
+	try:
+		nodes = fvars['QUERY_STRING'].split('&')
+		node_list = map(lambda x: x[1], filter(lambda x: x[0][:4] == 'node', map(lambda x: x.split('='), nodes)))
+		if not node_list or len(node_list) < 1:
+			raise Exception, 'No node list'
+	except Exception, e:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('GCNA: %r %s' % (e, str(e)))
+		write_err_async(request, 'No node names were given')
+		return None
+
+	errors = list()
+	ret = {}
+	for node_host in node_list:
+		try:
+			rc = RicciCommunicator(node_host)
+			cluster_name = rc.cluster_info()[0]
+			if not cluster_name:
+				errors.append('%s is not a member of a cluster' \
+					% cluster_name)
+				continue
+		except Exception, e:
+			if LUCI_DEBUG_MODE is True:
+				luci_log.debug_verbose('GCNA0: ricci: %s: %r %s' \
+					% (node_host, e, str(e)))
+			errors.append('Unable to communicate with the ricci agent on %s' \
+				% node_host)
+			continue
+
+		try:
+			conf = getClusterConf(rc)
+			node_names = getClusterConfNodes(conf)
+			if not node_names or len(node_names) < 1:
+				raise Exception, 'no nodes'
+		except Exception, e:
+			if LUCI_DEBUG_MODE is True:
+				luci_log.debug_verbose('GCNA1: ricci: %s: %r %s' \
+					% (node_host, e, str(e)))
+			errors.append('Unable to retrieve a list of cluster nodes from %s' \
+				% node_host)
+			continue
+		ret[cluster_name] = {
+			'cluster': cluster_name,
+			'num_nodes': len(node_names),
+			'clusternode': node_names
+		}
+
+	ret['errors'] = errors
+	xml_obj = result_to_xml((len(errors) < len(node_list), ret))
+	write_xml_resp(request, xml_obj)
+
+def get_sysinfo_async(self, request):
+	from HelperFunctions import get_system_info
+
+	fvars = GetReqVars(request, [ 'QUERY_STRING' ])
+	try:
+		nodes = fvars['QUERY_STRING'].split('&')
+		node_list = map(lambda x: x[1], filter(lambda x: x[0][:4] == 'node', map(lambda x: x.split('='), nodes)))
+		if not node_list or len(node_list) < 1:
+			raise Exception, 'No node list'
+	except Exception, e:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('GSIA: %r %s' % (e, str(e)))
+		write_err_async(request, 'No node names were given')
+		return None
+
+	ret = {}
+	try:
+		ret = get_system_info(self, node_list)
+	except Exception, e:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('GNFPA %r: %r %s' \
+				% (request['nodenames'], e, str(e)))
+		write_err_async(request, 'Error retrieving information')
+		return None
+	xml_obj = result_to_xml(True, { 'result': ret })
+	write_xml_resp(request, xml_obj)
--- conga/luci/site/luci/Extensions/HelperFunctions.py	2007/06/27 08:14:13	1.8
+++ conga/luci/site/luci/Extensions/HelperFunctions.py	2007/08/08 21:00:07	1.9
@@ -40,6 +40,10 @@
 			try:
 				rc = RicciCommunicator(host)
 				r['ricci'] = rc
+				try:
+					r['cluster_name'] = rc.cluster_info()[0]
+				except:
+					pass
 
 				if self.query_func is not None:
 					if self.query_args:
--- conga/luci/site/luci/Extensions/LuciClusterInfo.py	2007/07/30 02:24:15	1.9
+++ conga/luci/site/luci/Extensions/LuciClusterInfo.py	2007/08/08 21:00:07	1.10
@@ -1609,3 +1609,12 @@
 		clu_map['os'] = 'rhel5'
 		clu_map['isVirtualized'] = False
 	return clu_map
+
+def getClusterConfNodes(conf_dom):
+	try:
+		cluster_nodes = conf_dom.getElementsByTagName('clusternode')
+		return map(lambda x: str(x.getAttribute('name')), cluster_nodes)
+	except Exception, e:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('GCCN0: %r %s' % (e, str(e)))
+	return None
--- conga/luci/site/luci/Extensions/LuciZope.py	2007/07/27 16:43:47	1.3
+++ conga/luci/site/luci/Extensions/LuciZope.py	2007/08/08 21:00:07	1.4
@@ -126,15 +126,21 @@
 
 def GetReqVars(req, varlist):
 	ret = {}
+	from types import ListType;
+
 	for i in varlist:
 		pval = None
 		if req and req.has_key(i):
-			pval = req[i].strip()
+			pval = req[i]
+			if type(req[i]) is not ListType:
+				pval = req[i].strip()
 			if not pval:
 				pval = None
 		if req and pval is None:
 			if req.form and req.form.has_key(i):
-				pval = req.form[i].strip()
+				pval = req.form[i]
+				if type(req.form[i]) is not ListType:
+					pval.strip()
 				if not pval:
 					pval = None
 		ret[i] = pval
--- conga/luci/site/luci/Extensions/LuciZopeExternal.py	2007/06/25 16:03:38	1.2
+++ conga/luci/site/luci/Extensions/LuciZopeExternal.py	2007/08/08 21:00:07	1.3
@@ -51,3 +51,5 @@
 	get_content_data
 
 from system_adapters import get_sys_svc_list, validate_manage_svc
+
+from LuciZopeAsync import get_cluster_nodes_async, get_sysinfo_async
--- conga/luci/site/luci/Extensions/RicciQueries.py	2007/07/30 02:24:15	1.6
+++ conga/luci/site/luci/Extensions/RicciQueries.py	2007/08/08 21:00:07	1.7
@@ -721,3 +721,8 @@
 	if LUCI_DEBUG_MODE is True:
 		luci_log.debug_verbose('GCC2: no conf node found')
 	return None
+
+def set_xvm_key(rc, key_base64):
+	batch_str = '<module name="cluster"><request API_version="1.0"><function_call name="set_xvm_key"><var mutable="false" name="key_base64" type="string" value="%s"/></function_call></request></module>' % key_base64
+	ricci_xml = rc.batch_run(batch_str)
+	return batchAttemptResult(ricci_xml)
--- conga/luci/site/luci/Extensions/cluster_adapters.py	2007/07/30 02:24:15	1.264
+++ conga/luci/site/luci/Extensions/cluster_adapters.py	2007/08/08 21:00:07	1.265
@@ -21,12 +21,14 @@
 from ClusterModel.Method import Method
 
 import RicciQueries as rq
-from HelperFunctions import resolveOSType
+from HelperFunctions import resolveOSType, send_batch_to_hosts
 from LuciSyslog import get_logger
 from ResourceHandler import create_resource
 from homebase_adapters import parseHostForm
 from LuciClusterActions import propagateClusterConfAsync
 
+from LuciZopeAsync import get_cluster_nodes_async
+
 from LuciClusterInfo import getClusterInfo, \
 	getModelBuilder, LuciExtractCluModel
 
@@ -41,7 +43,7 @@
 	PRE_JOIN, REBOOT_TASK, REDIRECT_MSG, RESOURCES, RICCI_CONNECT_FAILURE, \
 	RICCI_CONNECT_FAILURE_MSG, SEND_CONF, SERVICE_ADD, SERVICE_CONFIG, \
 	SERVICE_LIST, SERVICES, START_NODE, TASKTYPE, VM_ADD, VM_CONFIG, \
-	REDIRECT_SEC, LUCI_CLUSTER_BASE_URL
+	REDIRECT_SEC, LUCI_CLUSTER_BASE_URL, FENCE_XVM_KEY_CREATE
 
 from FenceHandler import validateNewFenceDevice, \
 	validateFenceDevice, validate_fenceinstance, FD_VAL_SUCCESS
@@ -2125,6 +2127,56 @@
 	request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&busyfirst=true' \
 		% (baseurl, SERVICES, clustername))
 
+def validate_xvm_key_dist(self, request):
+	fvars = GetReqVars(request, [ '__NODE_HOSTNAME__', 'URL', 'clustername' ])
+
+	clustername = fvars['clustername']
+	if clustername is None:
+		return (False, { 'errors': [ 'No cluster name was given' ]})
+
+	host_list = fvars['__NODE_HOSTNAME__']
+	if not host_list:
+		return (False, { 'errors': [ 'No cluster node addresses were given', '%r' % request.form ]})
+
+	baseurl = fvars['URL'] or LUCI_CLUSTER_BASE_URL
+
+	try:
+		import base64
+		f = open('/dev/urandom', 'r')
+		new_key = f.read(4096)
+		f.close()
+		new_key = base64.encodestring(new_key)
+		if not new_key:
+			raise Exception, 'base64 encode failed'
+		new_key = new_key.replace('\n', '')
+	except Exception, e:
+		if LUCI_DEBUG_MODE is True:
+			luci_log.debug_verbose('VXKD0: /dev/urandom: %r %s' % (e, str(e)))
+		return (False, { 'errors': [ 'Unable to create a new fence_xvm key' ]})
+
+	errors = list()
+	ret = send_batch_to_hosts(host_list, 10, rq.set_xvm_key, new_key)
+	del new_key
+
+	for i in ret.iterkeys():
+		batch_num = None
+		batch_res = None
+
+		if ret[i].has_key('batch_result'):
+			batch_num, batch_res = ret[i]['batch_result']
+
+		if batch_num is None or batch_res is None:
+			errors.append('fence_xvm key creation failed for node "%s"' % i)
+			if LUCI_DEBUG_MODE is True:
+				luci_log.info('Setting fence_xvm key for node "%s" failed' % i)
+			continue
+
+		set_node_flag(self, clustername, i, batch_num,
+			FENCE_XVM_KEY_CREATE, 'Creating a fence_xvm key file')
+
+	request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&tab=2&busyfirst=true' \
+		% (baseurl, CLUSTER_CONFIG, clustername))
+
 def process_cluster_conf_editor(self, req):
 	if req.has_key('clustername'):
 		clustername = req['clustername'].strip() or None
@@ -2203,6 +2255,7 @@
 	55: validateDaemonProperties,
 	57: deleteFenceDevice,
 	58: validateNodeFenceConfig,
+	60: validate_xvm_key_dist,
 	80: process_cluster_conf_editor
 }
 
--- conga/luci/site/luci/Extensions/conga_constants.py	2007/07/27 16:43:47	1.42
+++ conga/luci/site/luci/Extensions/conga_constants.py	2007/08/08 21:00:07	1.43
@@ -54,6 +54,7 @@
 FENCEDEV_DELETE			= '57'
 FENCEDEV_NODE_CONFIG	= '58'
 SERVICE_MIGRATE			= '59'
+FENCE_XVM_KEY_CREATE	= '60'
 CONF_EDITOR				= '80'
 SYS_SERVICE_MANAGE		= '90'
 SYS_SERVICE_UPDATE		= '91'
--- conga/luci/site/luci/Extensions/homebase_adapters.py	2007/07/12 15:44:43	1.52
+++ conga/luci/site/luci/Extensions/homebase_adapters.py	2007/08/08 21:00:07	1.53
@@ -17,6 +17,8 @@
 	manageCluster, \
 	CLUSTER_NODE_NEED_AUTH
 
+from LuciClusterInfo import getClusterConfNodes
+
 from LuciZopePerm import havePermAddCluster, havePermRemCluster, \
 	havePermAddUser, havePermDelUser, havePermEditPerms, \
 	havePermRemStorage, havePermAddStorage
@@ -1297,7 +1299,3 @@
 				if LUCI_DEBUG_MODE is True:
 					luci_log.debug_verbose('getUserPerms2: user %s, obj %s: %r %s' % (userName, s[0], e, str(e)))
 	return perms
-
-def getClusterConfNodes(conf_dom):
-	cluster_nodes = conf_dom.getElementsByTagName('clusternode')
-	return map(lambda x: str(x.getAttribute('name')), cluster_nodes)
--- conga/luci/site/luci/Extensions/ClusterModel/Device.py	2007/07/27 17:02:35	1.3
+++ conga/luci/site/luci/Extensions/ClusterModel/Device.py	2007/08/08 21:00:08	1.4
@@ -13,7 +13,7 @@
 
 #New Power Controller Fence Agent names should be added to
 #the list below
-power_controller_list = ["fence_wti", "fence_apc","fence_apc_snmp"]
+power_controller_list = [ "fence_wti", "fence_apc", "fence_apc_snmp" ]
 
 class Device(TagObject):
   def __init__(self):
--- conga/make/version.in	2007/06/25 16:03:42	1.32
+++ conga/make/version.in	2007/08/08 21:00:08	1.33
@@ -1,5 +1,5 @@
 VERSION=0.10.0
-RELEASE=2_UNRELEASED
+RELEASE=4_UNRELEASED
 # Remove "_UNRELEASED" at release time.
 # Put release num at the beggining, 
 # so that after it gets released, it has 




More information about the Cluster-devel mailing list