CVSROOT: /cvs/cluster Module name: conga Changes by: [EMAIL PROTECTED] 2008-01-14 20:51:42
Modified files: . : conga.spec.in.in luci/site/luci/Extensions: cluster_adapters.py LuciDB.py luci/cluster : busy_wait-macro Log message: Fix bz239387 (RFE: add timeouts for actions that can leave cluster unreachable) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/conga.spec.in.in.diff?cvsroot=cluster&r1=1.91&r2=1.92 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/cluster_adapters.py.diff?cvsroot=cluster&r1=1.277&r2=1.278 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/LuciDB.py.diff?cvsroot=cluster&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/cluster/busy_wait-macro.diff?cvsroot=cluster&r1=1.1&r2=1.2 --- conga/conga.spec.in.in 2008/01/03 16:27:48 1.91 +++ conga/conga.spec.in.in 2008/01/14 20:51:42 1.92 @@ -302,6 +302,7 @@ - Fixed bz253727 (RFE: graphical view should be default in partiton tables view) - Fixed bz337041 (Add option to not fail-back service) - Fixed bz264161 (RFE: support setting the "__independent_subtree" attribute on cluster resources) +- Fixed bz239387 (RFE: add timeouts for actions that can leave cluster unreachable) * Mon Aug 27 2007 Ryan McCabe <[EMAIL PROTECTED]> 0.10.0-6 - Fixed bz253783 --- conga/luci/site/luci/Extensions/cluster_adapters.py 2008/01/02 21:00:32 1.277 +++ conga/luci/site/luci/Extensions/cluster_adapters.py 2008/01/14 20:51:42 1.278 @@ -40,7 +40,7 @@ batch_status, extract_module_status from LuciDB import manageCluster, createClusterSystems, \ - setNodeStatus, getStorageNode, getClusterFlags, \ + setNodeStatus, getStorageNode, getClusterFlags, del_node_flag, \ getClusterNode, buildClusterCreateFlags, getClusterDBObj, \ resolve_nodename, set_node_flag, getRicciAgent, \ CLUSTER_NODE_NEED_AUTH @@ -1102,6 +1102,30 @@ request.RESPONSE.redirect('%s?pagetype=%s&clustername=%s&tab=2&busyfirst=true' \ % (baseurl, CLUSTER_CONFIG, clustername)) +def validate_stop_waiting(self, request): + fvar = GetReqVars(request, [ 'clustername', 'node', 'batchid', 'refreshurl' ]) + + batchid = fvar['batchid'] + node = fvar['node'] + clustername = fvar['clustername'] + + if node is None: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('VSW0: no node name given') + + if clustername is None: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('VSW1: no cluster name was given') + + if node and clustername: + try: + del_node_flag(self, clustername, node, batchid) + except Exception, e: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('VSW2: [%s %s %s] %r %s' \ + % (node, clustername, batchid, e, str(e))) + request.RESPONSE.redirect(fvar['refreshurl']) + def process_cluster_conf_editor(self, req): if req.has_key('clustername'): clustername = req['clustername'].strip() or None @@ -1181,6 +1205,7 @@ 57: deleteFenceDevice, 58: validateNodeFenceConfig, 60: validate_xvm_key_dist, + 61: validate_stop_waiting, 80: process_cluster_conf_editor, 1001: validate_clusvc_async } @@ -1524,6 +1549,7 @@ isBusy = False redirect_message = False nodereports = list() + report_index = 0 fvar = GetReqVars(req, [ 'clustername', 'URL' ]) busy_map['nodereports'] = nodereports @@ -1571,13 +1597,21 @@ # If complete, report status and remove flag. for item in items: + node_report = {} tasktype = item[1].getProperty(TASKTYPE) if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB3: task type for %s = %s' \ % (item[0], tasktype)) + + ricci = item[0].split('____')[0] + + node_report['node'] = ricci + node_report['tasktype'] = tasktype + node_report['clustername'] = cluname + node_report['report_index'] = report_index + report_index += 1 if tasktype == CLUSTER_ADD or tasktype == NODE_ADD: - node_report = {} node_report['isnodecreation'] = True # Default value node_report['iserror'] = False @@ -1585,14 +1619,13 @@ batch_xml = None # This removes the 'flag' suffix - ricci = item[0].split('____') if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB4: using rc host %s for item %s' \ - % (ricci[0], item[0])) + % (ricci, item[0])) try: - rc = RicciCommunicator(ricci[0]) + rc = RicciCommunicator(ricci) if not rc: rc = None if LUCI_DEBUG_MODE is True: @@ -1615,12 +1648,14 @@ luci_log.debug_verbose('ICB8: failed to get batch_id from %s: %r %s' % (item[0], e, str(e))) if batch_id is not None: + node_report['batchid'] = batch_id try: batch_xml = rc.batch_report(batch_id) if batch_xml is not None: if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB9: batch_xml for %s from batch_report is not None -- getting batch status' % batch_id) (creation_status, total) = batch_status(batch_xml) + try: if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB10: batch status returned (%d,%d)' % (creation_status, total)) @@ -1669,7 +1704,7 @@ # an error was encountered if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB17: %s: CS %d for %s' \ - % (cluname, creation_status, ricci[0])) + % (cluname, creation_status, ricci)) if creation_status == RICCI_CONNECT_FAILURE: laststatus = item[1].getProperty(LAST_STATUS) @@ -1737,8 +1772,8 @@ try: if del_db_obj is True: if LUCI_DEBUG_MODE is True: - luci_log.debug_verbose('ICB19: %s node creation failed for %s: %d: deleting DB entry' % (cluname, ricci[0], creation_status)) - clusterfolder.manage_delObjects([ricci[0]]) + luci_log.debug_verbose('ICB19: %s node creation failed for %s: %d: deleting DB entry' % (cluname, ricci, creation_status)) + clusterfolder.manage_delObjects([ricci]) clusterfolder.manage_delObjects([item[0]]) except Exception, e: if LUCI_DEBUG_MODE is True: @@ -1764,8 +1799,8 @@ % (item[0], e, str(e))) continue else: - busy_map['busy'] = 'true' isBusy = True + busy_map['busy'] = 'true' node_report['statusmessage'] = 'Node still being created' node_report['statusindex'] = creation_status nodereports.append(node_report) @@ -1783,13 +1818,11 @@ luci_log.debug_verbose('ICB23: last_status err: %s %d: %r %s' % (item[0], creation_status, e, str(e))) continue else: - node_report = {} node_report['isnodecreation'] = False # This removes the 'flag' suffix - ricci = item[0].split('____') try: - rc = RicciCommunicator(ricci[0]) + rc = RicciCommunicator(ricci) except Exception, e: rc = None finished = -1 @@ -1797,7 +1830,7 @@ if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('ICB24: ricci error: %s: %r %s' \ - % (ricci[0], e, str(e))) + % (ricci, e, str(e))) if rc is not None: batch_num = item[1].getProperty(BATCH_ID) @@ -1825,9 +1858,8 @@ % (item[0], e, str(e))) busy_map['busy'] = None else: - node_report = {} - busy_map['busy'] = 'true' isBusy = True + busy_map['busy'] = 'true' node_report['desc'] = item[1].getProperty(FLAG_DESC) nodereports.append(node_report) --- conga/luci/site/luci/Extensions/LuciDB.py 2007/08/20 16:31:13 1.7 +++ conga/luci/site/luci/Extensions/LuciDB.py 2008/01/14 20:51:42 1.8 @@ -84,6 +84,38 @@ luci_log.debug_verbose('clearNodeStatus0: %r %s' \ % (e, str(e))) +def del_node_flag(self, cluname, agent, batchid=None): + path = str('%s%s' % (CLUSTER_FOLDER_PATH, cluname)) + objname = '%s____flag' % agent + + try: + flag_obj = self.restrictedTraverse(str('%s/%s' % (path, objname))) + clusterfolder = self.restrictedTraverse(path) + except Exception, e: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('DNF0: %s/%s: %s %r %s' \ + % (path, objname, flag_obj[0], e, str(e))) + return False + + if batchid: + try: + bid = flag_obj.getProperty(BATCH_ID) + if bid != batchid: + raise Exception, 'mismatch: got %s, wanted %s' % (bid, batchid) + except Exception, e1: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('DNF1: unable to find flag with bid: %s for %s/%s: %r %s' % (batchid, path, objname, e1, str(e1))) + return False + + try: + clusterfolder.manage_delObjects([objname]) + except Exception, e: + if LUCI_DEBUG_MODE is True: + luci_log.debug_verbose('DNF2: %s/%s: %r %s' \ + % (path, objname, e, str(e))) + return False + return True + def set_node_flag(self, cluname, agent, batchid, task, desc): path = str('%s%s' % (CLUSTER_FOLDER_PATH, cluname)) batch_id = str(batchid) @@ -99,8 +131,8 @@ flag.manage_addProperty(TASKTYPE, task, 'string') flag.manage_addProperty(FLAG_DESC, desc, 'string') except Exception, e: - errmsg = 'SNF0: error creating flag (%s,%s,%s) at %s: %s' \ - % (batch_id, task, desc, objpath, str(e)) + errmsg = 'Error creating flag (bid: %s task: %s desc: %s) at %s: %s' \ + % (batch_id, task, desc, objpath, str(e)) if LUCI_DEBUG_MODE is True: luci_log.debug_verbose('SNF0: %r %s' % (e, errmsg)) raise Exception, errmsg --- conga/luci/cluster/busy_wait-macro 2007/11/19 18:22:48 1.1 +++ conga/luci/cluster/busy_wait-macro 2008/01/14 20:51:42 1.2 @@ -1,62 +1,70 @@ <div metal:define-macro="busywaitpage"> - <table> - <tr><td> - <h2>Please be patient - this cluster's configuration is being modified.</h2> - </td></tr> - - <tr><td> - <img src="100wait.gif" /> - </td></tr> + <h2>Please be patient - this cluster's configuration is being modified.</h2> - <span tal:define="global nodereports isBusy/nodereports" /> + <p><img src="100wait.gif" /></p> + + <span tal:define="global nodereports isBusy/nodereports" /> + + <div tal:repeat="nodereport nodereports"> + <tal:block + tal:condition="python:nodereport.get('isnodecreation') != True"> + + <h3><span tal:replace="nodereport/desc" /></h3> + </tal:block> + + <tal:block + tal:condition="python:nodereport.get('isnodecreation') == True"> - <tr tal:repeat="nodereport nodereports"><td> <tal:block - tal:condition="python:nodereport.get('isnodecreation') != True"> + tal:condition="python:nodereport.get('iserror') == True"> + + <h3><span tal:content="nodereport/desc" /></h3> - <h2><span tal:replace="nodereport/desc" /></h2> + <span class="errmsg" tal:content="nodereport/errormessage" /> </tal:block> - <tal:block - tal:condition="python:nodereport.get('isnodecreation') == True"> + <tal:block tal:condition="python:nodereport.get('iserror') != True"> + <h3><span tal:content="nodereport/desc" /></h3> + <em tal:content="nodereport/statusmessage | nothing" /> + <br/> - <tal:block - tal:condition="python:nodereport.get('iserror') == True"> + <tal:block tal:condition="python: nodereport['statusindex'] < 1"> + <img src="notstarted.png" /> + </tal:block> - <h2><span tal:content="nodereport/desc" /></h2> + <tal:block tal:condition="python: nodereport['statusindex'] == 1 or nodereport['statusindex'] == 2"> + <img src="installed.png" alt="[cluster software installed]" /> + </tal:block> - <span class="errmsg" - tal:content="nodereport/errormessage" /> + <tal:block tal:condition="python: nodereport['statusindex'] == 3"> + <img src="rebooted.png" alt="[cluster node rebooted]" /> </tal:block> - <tal:block - tal:condition="python:nodereport.get('iserror') != True"> + <tal:block tal:condition="python: nodereport['statusindex'] == 4 or nodereport['statusindex'] == 5"> + <img src="configured.png" alt="[cluster node configured]" /> + </tal:block> - <h2><span tal:content="nodereport/desc" /></h2> - <em tal:content="nodereport/statusmessage | nothing" /> - <br/> - - <tal:block tal:condition="python: nodereport['statusindex'] < 1"> - <img src="notstarted.png" /> - </tal:block> - - <tal:block tal:condition="python: nodereport['statusindex'] == 1 or nodereport['statusindex'] == 2"> - <img src="installed.png" alt="[cluster software installed]" /> - </tal:block> - - <tal:block tal:condition="python: nodereport['statusindex'] == 3"> - <img src="rebooted.png" alt="[cluster node rebooted]" /> - </tal:block> - - <tal:block tal:condition="python: nodereport['statusindex'] == 4 or nodereport['statusindex'] == 5"> - <img src="configured.png" alt="[cluster node configured]" /> - </tal:block> - - <tal:block tal:condition="python: nodereport['statusindex'] == 6"> - <img src="joined.png" alt="[cluster node joined cluster]" /> - </tal:block> + <tal:block tal:condition="python: nodereport['statusindex'] == 6"> + <img src="joined.png" alt="[cluster node joined cluster]" /> </tal:block> </tal:block> - </td></tr> - </table> + </tal:block> + + <div> + <form method="post" action="" + tal:attributes="name python:'stop_waiting_form%s' % nodereport.get('report_index')"> + + <input type="hidden" name="pagetype" value="61" /> + <input type="hidden" name="clustername" + tal:attributes="value nodereport/clustername | nothing" /> + <input type="hidden" name="node" + tal:attributes="value nodereport/node | nothing" /> + <input type="hidden" name="refreshurl" + tal:attributes="value nodereport/refreshurl | request/URL |string:." /> + <a href="javascript:void(0)" + tal:attributes="onclick python:'javascript:document.stop_waiting_form%s.submit()' % nodereport.get('report_index')">Stop waiting for this job to complete</a> + </form> + </div> + </div> + <hr/> </div>