From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 8 Aug 2007 21:00:14 -0000 Subject: [Cluster-devel] conga luci/cluster/fence_device.js luci/cluste ... Message-ID: <20070808210014.29749.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 @@
+ +
+ --- 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 @@ + + @@ -917,7 +923,7 @@
-
+ + + +
 
+ XVM fence daemon key distribution + + + + + + + + + + + + +
+
+
+ +
+ + + + + + + + + + + + + + + + + +
+ Enter a node hostname from the host cluster + + +
+ Enter a node hostname from the hosted (virtual) cluster + + +
+ +
+ + @@ -974,7 +1042,8 @@
+ id="fence_config_submit" + onClick="validate_form(this.form)" />
@@ -5301,6 +5370,10 @@
+
+ +
+
--- 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 = '' % 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