From mboxrd@z Thu Jan 1 00:00:00 1970 From: kupcevic@sourceware.org Date: 16 Oct 2006 07:39:28 -0000 Subject: [Cluster-devel] conga/luci site/luci/Extensions/StorageReport. ... Message-ID: <20061016073928.22741.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: kupcevic at sourceware.org 2006-10-16 07:39:27 Modified files: luci/site/luci/Extensions: StorageReport.py Variable.py ricci_communicator.py luci/storage : form-macros Added files: luci/storage : check-batch Log message: luci storage: - use async calls to commit storage changes - detailed error reporting during commits Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&r1=1.17&r2=1.18 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/Variable.py.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/ricci_communicator.py.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/check-batch.diff?cvsroot=cluster&r1=NONE&r2=1.1 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/storage/form-macros.diff?cvsroot=cluster&r1=1.14&r2=1.15 --- conga/luci/site/luci/Extensions/StorageReport.py 2006/10/15 22:34:54 1.17 +++ conga/luci/site/luci/Extensions/StorageReport.py 2006/10/16 07:39:27 1.18 @@ -10,7 +10,7 @@ from conga_storage_constants import * from HelperFunctions import * -from ricci_communicator import get_ricci_communicator +from ricci_communicator import get_ricci_communicator, batch_status, extract_module_status @@ -811,14 +811,10 @@ return [valid, var_name, msg] -# TODO: implement -def apply(self, ricci, storage_report, request, main_URL): + +def apply(self, ricci, storage_report, request): if validate(self, storage_report, request) != 'OK': - return 'Internal error: input not validated!!!' - - #return 'size has to be within limits' - #return request - #return main_URL + raise 'Internal error: input not validated!!!' session = request.SESSION @@ -833,6 +829,8 @@ path = request[PT_PATH] + batch_id = '' + if object_type == 'bd': bd_data = get_bd_data(self, storage_report, mapper_id, path) bd_xml = bd_data['xml'].cloneNode(True) @@ -853,11 +851,8 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error removing ' + path + '\n' + res.toprettyxml() - return err_msg + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass @@ -978,51 +973,10 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error modifying ' + path + '\n' + res.toprettyxml() - return err_msg - module_r = None - for node in res.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r == None: - raise 'missing in ' - if module_r.getAttribute('status') != '0': - raise 'error retrieving storage report' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == RESPONSE_TAG: - resp_r = node - if resp_r == None: - raise 'missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == FUNC_RESP_TAG: - fr_r = node - if fr_r == None: - raise 'missing in ' - bd_var = None - for node in fr_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('name') == 'bd': - bd_var = node - if bd_var == None: - raise 'missing in ' - bd_xml = None - for node in bd_var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TYPE: - bd_xml = node.cloneNode(True) - path = bd_xml.getAttribute('path') + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass - pass - + elif object_type == 'bd_template': @@ -1149,51 +1103,10 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error creating new ' + path + '\n' + res.toprettyxml() - return err_msg - module_r = None - for node in res.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r == None: - raise 'missing in ' - if module_r.getAttribute('status') != '0': - raise 'error retrieving storage report' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == RESPONSE_TAG: - resp_r = node - if resp_r == None: - raise 'missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == FUNC_RESP_TAG: - fr_r = node - if fr_r == None: - raise 'missing in ' - bd_var = None - for node in fr_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('name') == 'bd': - bd_var = node - if bd_var == None: - raise 'missing in ' - bd_xml = None - for node in bd_var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TYPE: - bd_xml = node.cloneNode(True) - path = bd_xml.getAttribute('path') + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass - pass - + elif object_type == 'mapper': @@ -1217,13 +1130,11 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error removing ' + mapper_id + '\n' + res.toprettyxml() - return err_msg + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass + elif action_type == 'Apply': # props props_xml = None @@ -1274,51 +1185,10 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error modifying ' + mapper_id + '\n' + res.toprettyxml() - return err_msg - module_r = None - for node in res.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r == None: - raise 'missing in ' - if module_r.getAttribute('status') != '0': - raise 'error retrieving storage report' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == RESPONSE_TAG: - resp_r = node - if resp_r == None: - raise 'missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == FUNC_RESP_TAG: - fr_r = node - if fr_r == None: - raise 'missing in ' - mapper_var = None - for node in fr_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('name') == 'mapper': - mapper_var = node - if mapper_var == None: - raise 'missing in ' - mapper_xml = None - for node in mapper_var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_TYPE: - mapper_xml = node.cloneNode(True) - path = mapper_xml.getAttribute('mapper_id') + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass - pass - + elif object_type == 'mapper_template': @@ -1388,51 +1258,10 @@ module.appendChild(req) batch.appendChild(module) - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error creating new ' + mapper_type + '\n' + res.toprettyxml() - return err_msg - module_r = None - for node in res.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r == None: - raise 'missing in ' - if module_r.getAttribute('status') != '0': - raise 'error retrieving storage report' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == RESPONSE_TAG: - resp_r = node - if resp_r == None: - raise 'missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == FUNC_RESP_TAG: - fr_r = node - if fr_r == None: - raise 'missing in ' - mapper_var = None - for node in fr_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('name') == 'mapper': - mapper_var = node - if mapper_var == None: - raise 'missing in ' - mapper_xml = None - for node in mapper_var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'mapper': - mapper_xml = node.cloneNode(True) - mapper_id = mapper_xml.getAttribute('mapper_id') + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass - pass - + @@ -1470,88 +1299,129 @@ module.appendChild(req) batch.appendChild(module) - #return batch.toprettyxml() - - res = ricci.process_batch(batch, False) - if res.getAttribute('status') != '0': - invalidate_storage_report(request.SESSION, storagename) - err_msg = 'Error adding sources to ' + mapper_type + ' ' + mapper_id + '\n' + res.toprettyxml() - return err_msg - module_r = None - for node in res.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r == None: - raise 'missing in ' - if module_r.getAttribute('status') != '0': - raise 'error retrieving storage report' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == RESPONSE_TAG: - resp_r = node - if resp_r == None: - raise 'missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == FUNC_RESP_TAG: - fr_r = node - if fr_r == None: - raise 'missing in ' - mapper_var = None - for node in fr_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('name') == 'mapper': - mapper_var = node - if mapper_var == None: - raise 'missing in ' - mapper_xml = None - for node in mapper_var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'mapper': - mapper_xml = node.cloneNode(True) - mapper_id = mapper_xml.getAttribute('mapper_id') + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') pass pass - - - - - invalidate_storage_report(request.SESSION, storagename) - - goto_url = main_URL + '?storagename=' + storagename - if object_type == 'bd_template': - goto_url += '&pagetype=' + VIEW_BD - goto_url += '&' + PT_PATH + '=' + path - elif object_type == 'bd': - if action_type == 'Remove': - goto_url += '&pagetype=' + VIEW_MAPPER - else: - goto_url += '&pagetype=' + VIEW_BD - goto_url += '&' + PT_PATH + '=' + request[PT_PATH] - elif object_type == 'mapper': - if action_type == 'Remove': - goto_url += '&pagetype=' + VIEW_MAPPERS + if batch_id == '': + raise 'unsupported function' + else: + invalidate_storage_report(request.SESSION, storagename) + return batch_id; + + +def get_storage_batch_result(self, + storagename, + ricci, + index_html_URL, + batch_id): + error = True # ricci reported failure or no ricci + completed = False # no batch, or batch done (defined if no error) + url = index_html_URL # redirect URL + msg = 'Unknown error occured' + + if ricci == None: + # ricci down + error = True + url = url + msg = 'Unable to contact ' + storagename + else: + batch = 'no batch' + try: + batch = ricci.batch_report(batch_id) + except: + pass + if batch == 'no batch': + error = True + url = url + msg = 'Ricci on ' + storagename + ' responded with error. No detailed info available.' + elif batch == None: + # no such batch + error = False + completed = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'No such batch' else: - goto_url += '&pagetype=' + VIEW_MAPPER - elif object_type == 'mapper_template': - goto_url += '&pagetype=' + VIEW_MAPPER - elif object_type == 'add_sources': - goto_url += '&pagetype=' + VIEW_MAPPER - goto_url += '&' + PT_MAPPER_TYPE + '=' + mapper_type - goto_url += '&' + PT_MAPPER_ID + '=' + mapper_id - redirect_html = '\n' - redirect_html += ' \n' - redirect_html += '\n' - redirect_html += '\n' - #redirect_html += 'Reloading Storage Info...\n' - redirect_html += '' - return redirect_html + DEFAULT_ERROR = 'extract_module_status() failed' + code, err_msg = DEFAULT_ERROR, '' + try: + code, err_msg = extract_module_status(batch, 1) + except: + pass + if code == DEFAULT_ERROR: + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Ricci on ' + storagename + ' sent malformed response' + elif code == -101 or code == -102: + # in progress + error = False + completed = False + msg = 'Task still in progress' + elif code == -103: + # module removed from scheduler + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Ricci on ' + storagename + ' removed request from scheduler. File bug report against ricci.' + elif code == -104: + # module failure + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Ricci on ' + storagename + ' failed to execute storage module; reinstall it.' + elif code == -2: + # API error + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Luci server used invalid API to communicate with ' + storagename + '. File a bug report against luci.' + elif code == -1: + # undefined error + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Reason for failure (as reported by ' + storagename + '): ' + err_msg + elif code == 0: + # no error + error = False + completed = True + # TODO: implement proper redirect + url = get_commit_redirect(url, + storagename, + batch) + msg = 'Done successfully' + elif code == 1: + # mid-air + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Mid-Air collision (storage on ' + storagename + ' has changed since last probe). ' + elif code == 2: + # validation error + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Validation error. File bug report against Luci.' + elif code == 3: + # unmount error + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Unmount failure: ' + err_msg + elif code == 4: + # clvmd error + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'clvmd (clustered LVM daemon) is not running on ' + storagename + '. Start it and try again.' + elif code == 5: + # not quorate + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = 'Cluster quorum is required, and yet cluster is not quorate. Start cluster, and try again.' + elif code > 5: + error = True + url += '?' + STONAME + '=' + storagename + '&' + PAGETYPE + '=' + STORAGE + msg = err_msg + + return {'error' : error, + 'completed' : completed, + 'redirect_url' : url, + 'msg' : msg} @@ -1561,6 +1431,74 @@ +def get_commit_redirect(main_url, + storagename, + batch_xml): + module_r = None + for node in batch_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'module': + module_r = node + if module_r == None: + raise 'missing in ' + resp_r = None + for node in module_r.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == RESPONSE_TAG: + resp_r = node + if resp_r == None: + raise 'missing in ' + fr_r = None + for node in resp_r.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == FUNC_RESP_TAG: + fr_r = node + if fr_r == None: + raise 'missing in ' + vars = {} + for node in fr_r.childNodes: + try: + var = parse_variable(node) + vars[var.get_name()] = var + except: + pass + pass + + + mapper_id = '' + mapper_type = '' + bd_path = '' + if 'mapper' in vars: + mapper = vars['mapper'].get_value() + mapper_type = mapper.getAttribute('mapper_type') + mapper_id = mapper.getAttribute('mapper_id') + if 'bd' in vars: + bd = vars['bd'].get_value() + bd_path = bd.getAttribute('path') + mapper_type = bd.getAttribute('mapper_type') + mapper_id = bd.getAttribute('mapper_id') + + url = main_url + '?' + url += STONAME + '=' + storagename + if mapper_type != '': + url += '&' + PT_MAPPER_TYPE + '=' + mapper_type + if mapper_id != '': + url += '&' + PT_MAPPER_ID + '=' + mapper_id + if bd_path != '': + url += '&' + PT_PATH + '=' + bd_path + + if mapper_type == '': + url += '&' + PAGETYPE + '=' + STORAGE + elif bd_path != '': + url += '&' + PAGETYPE + '=' + VIEW_BD + else: + url += '&' + PAGETYPE + '=' + VIEW_MAPPER + + return url + + + + def get_bd_data_internal(session, bd_xml, mapper_xml): data = {} --- conga/luci/site/luci/Extensions/Variable.py 2006/10/16 04:26:19 1.3 +++ conga/luci/site/luci/Extensions/Variable.py 2006/10/16 07:39:27 1.4 @@ -49,12 +49,12 @@ value = [] for kid in node.childNodes: if kid.nodeType == xml.dom.Node.ELEMENT_NODE: - value.append(kid) + value.append(kid.cloneNode(True)) return VariableList(attrs_dir['name'], value, mods, VARIABLE_TYPE_LIST_XML) elif attrs_dir['type'] == VARIABLE_TYPE_XML: for kid in node.childNodes: if kid.nodeType == xml.dom.Node.ELEMENT_NODE: - value = kid + value = kid.cloneNode(True) break elif attrs_dir['type'] == VARIABLE_TYPE_INT: value = int(attrs_dir['value']) --- conga/luci/site/luci/Extensions/ricci_communicator.py 2006/10/16 04:26:19 1.8 +++ conga/luci/site/luci/Extensions/ricci_communicator.py 2006/10/16 07:39:27 1.9 @@ -297,7 +297,7 @@ # -102 - scheduled # -103 - removed from schedule # -104 - failed to execute module -# +# # >-3 - module executed. Following codes are defined: # -2 - API error # -1 - undefined error occured (msg not necesarily very informative) /cvs/cluster/conga/luci/storage/check-batch,v --> standard output revision 1.1 --- conga/luci/storage/check-batch +++ - 2006-10-16 07:39:28.551973000 +0000 @@ -0,0 +1,60 @@ + + + + + + + +FAILURE + +You are not authorized to modify storage system !!! + + + + + + + + +DONE + + + + + +NOT_DONE + + + + + + + +FAILURE + + + + + + + + + --- conga/luci/storage/form-macros 2006/10/15 22:34:54 1.14 +++ conga/luci/storage/form-macros 2006/10/16 07:39:27 1.15 @@ -99,6 +99,87 @@
+ +
+
+ +
+ + + + + +
+ + + + + +
@@ -111,11 +192,6 @@
- - - here.apply() response -