From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 24 Sep 2007 19:48:34 -0000 Subject: [Cluster-devel] conga/luci/site/luci/Extensions StorageReport. ... Message-ID: <20070924194834.23940.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-09-24 19:48:34 Modified files: luci/site/luci/Extensions: StorageReport.py storage_adapters.py Log message: Whitespace, readability cleanup Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/StorageReport.py.diff?cvsroot=cluster&r1=1.26&r2=1.27 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/luci/site/luci/Extensions/storage_adapters.py.diff?cvsroot=cluster&r1=1.11&r2=1.12 --- conga/luci/site/luci/Extensions/StorageReport.py 2007/08/09 04:37:20 1.26 +++ conga/luci/site/luci/Extensions/StorageReport.py 2007/09/24 19:48:34 1.27 @@ -34,2066 +34,2061 @@ from ricci_communicator import extract_module_status - SESSION_STORAGE_XML_REPORT = 'storage_xml_report_dir' - class StorageReport: + def __init__(self, storage_xml_report): + self.__report = storage_xml_report#.cloneNode(True) - def __init__(self, storage_xml_report): - self.__report = storage_xml_report#.cloneNode(True) - - self.__mappers = None - self.__m_temps = None - for node in self.__report.childNodes: - try: - var = parse_variable(node) - if var.get_name() == 'mappers': - self.__mappers = var.get_value() - if var.get_name() == 'mapper_templates': - self.__m_temps = var.get_value() - except: - pass - if self.__mappers is None or self.__m_temps is None: - raise Exception, 'invalid storage_xml_report' - - self.__mapp_dir = {} # holds mapper lists by mapper_type - for mapp_node in self.__mappers: - m_type = mapp_node.getAttribute('mapper_type') - if not (m_type in self.__mapp_dir): - self.__mapp_dir[m_type] = [] - self.__mapp_dir[m_type].append(mapp_node)#.cloneNode(True)) - - self.__m_temps_dir = {} # holds mapper_template lists by mapper_type - for temp_node in self.__m_temps: - m_type = temp_node.getAttribute('mapper_type') - if not (m_type in self.__m_temps_dir): - self.__m_temps_dir[m_type] = [] - self.__m_temps_dir[m_type].append(temp_node)#.cloneNode(True)) - # - - - - - - def get_xml_report(self): - return self.__report#.cloneNode(True) - - - def get_mappers(self, mapper_type=''): - l = [] - if mapper_type == '': - l = self.__mappers - elif mapper_type in self.__mapp_dir: - l = self.__mapp_dir[mapper_type] - r = [] - for s in l: - r.append(s)#s.cloneNode(True)) - return r - - - def get_mappers_dir(self): - r = {} - for mapper_type in self.__mapp_dir: - l = [] - for m in self.__mapp_dir[mapper_type]: - l.append(m)#.cloneNode(True)) - r[mapper_type] = l - return r - - - def get_mapper(self, mapper_id): - if mapper_id == '': - raise Exception, 'empty mapper_id!!!' - for m in self.__mappers: - if m.getAttribute('mapper_id') == mapper_id: - return m#.cloneNode(True) - return None - - - def get_mapper_temps_dir(self): - r = {} - for mapper_type in self.__m_temps_dir: - l = [] - for m in self.__m_temps_dir[mapper_type]: - l.append(m)#.cloneNode(True)) - r[mapper_type] = l - return r - - - def get_mapper_temps(self, mapper_type=''): - l = [] - if mapper_type == '': - l = self.__m_temps - elif mapper_type in self.__m_temps_dir: - l = self.__m_temps_dir[mapper_type] - r = [] - for s in l: - r.append(s)#.cloneNode(True)) - return r - - - def get_targets(self, mapper): - if mapper is None: - return [] - - targets_list = [] - for node in mapper.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_TARGETS_TAG: - targets_xml = node - for node in targets_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TYPE: - targets_list.append(node)#.cloneNode(True)) - return targets_list - - - def get_new_targets(self, mapper): - if mapper is None: - return [] - - targets_list = [] - for node in mapper.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_NEW_TARGETS_TAG: - targets_xml = node - for node in targets_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TEMPLATE: - targets_list.append(node)#.cloneNode(True)) - return targets_list - - - def get_sources(self, mapper): - if mapper is None: - return [] - - targets_list = [] - for node in mapper.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_SOURCES_TAG: - targets_xml = node - for node in targets_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TYPE: - targets_list.append(node)#.cloneNode(True)) - return targets_list - - - def get_new_sources(self, mapper): - if mapper is None: - return [] - - targets_list = [] - for node in mapper.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_NEW_SOURCES_TAG: - targets_xml = node - for node in targets_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TYPE: - targets_list.append(node)#.cloneNode(True)) - return targets_list - - - def get_mapper_props(self, mapper): - if mapper is None: - return None - - props = None - for node in mapper.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props = node#.cloneNode(True) - if props is None: - raise Exception, 'mapper missing properties tag' - return props - - - def get_target(self, mapper_id, path): - mapper = self.get_mapper(mapper_id) - if mapper is None: - return None - - targets = self.get_targets(mapper) - for t_xml in targets: - if t_xml.getAttribute('path') == path: - return t_xml#.cloneNode(True) - return None + self.__mappers = None + self.__m_temps = None + for node in self.__report.childNodes: + try: + var = parse_variable(node) + if var.get_name() == 'mappers': + self.__mappers = var.get_value() + if var.get_name() == 'mapper_templates': + self.__m_temps = var.get_value() + except: + pass + if self.__mappers is None or self.__m_temps is None: + raise Exception, 'invalid storage_xml_report' + + self.__mapp_dir = {} # holds mapper lists by mapper_type + for mapp_node in self.__mappers: + m_type = mapp_node.getAttribute('mapper_type') + if not (m_type in self.__mapp_dir): + self.__mapp_dir[m_type] = [] + self.__mapp_dir[m_type].append(mapp_node)#.cloneNode(True)) + + self.__m_temps_dir = {} # holds mapper_template lists by mapper_type + for temp_node in self.__m_temps: + m_type = temp_node.getAttribute('mapper_type') + if not (m_type in self.__m_temps_dir): + self.__m_temps_dir[m_type] = [] + self.__m_temps_dir[m_type].append(temp_node)#.cloneNode(True)) + # + + def get_xml_report(self): + return self.__report#.cloneNode(True) + + def get_mappers(self, mapper_type=''): + l = [] + if mapper_type == '': + l = self.__mappers + elif mapper_type in self.__mapp_dir: + l = self.__mapp_dir[mapper_type] + r = [] + for s in l: + r.append(s)#s.cloneNode(True)) + return r + + def get_mappers_dir(self): + r = {} + for mapper_type in self.__mapp_dir: + l = [] + for m in self.__mapp_dir[mapper_type]: + l.append(m)#.cloneNode(True)) + r[mapper_type] = l + return r + + def get_mapper(self, mapper_id): + if mapper_id == '': + raise Exception, 'empty mapper_id!!!' + for m in self.__mappers: + if m.getAttribute('mapper_id') == mapper_id: + return m#.cloneNode(True) + return None + + def get_mapper_temps_dir(self): + r = {} + for mapper_type in self.__m_temps_dir: + l = [] + for m in self.__m_temps_dir[mapper_type]: + l.append(m)#.cloneNode(True)) + r[mapper_type] = l + return r + + def get_mapper_temps(self, mapper_type=''): + l = [] + if mapper_type == '': + l = self.__m_temps + elif mapper_type in self.__m_temps_dir: + l = self.__m_temps_dir[mapper_type] + r = [] + for s in l: + r.append(s)#.cloneNode(True)) + return r + + def get_targets(self, mapper): + if mapper is None: + return [] + + targets_list = [] + for node in mapper.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_TARGETS_TAG: + targets_xml = node + for node in targets_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == BD_TYPE: + targets_list.append(node)#.cloneNode(True)) + return targets_list + + def get_new_targets(self, mapper): + if mapper is None: + return [] + + targets_list = [] + for node in mapper.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_NEW_TARGETS_TAG: + targets_xml = node + for node in targets_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == BD_TEMPLATE: + targets_list.append(node)#.cloneNode(True)) + return targets_list + + def get_sources(self, mapper): + if mapper is None: + return [] + + targets_list = [] + for node in mapper.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_SOURCES_TAG: + targets_xml = node + for node in targets_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == BD_TYPE: + targets_list.append(node)#.cloneNode(True)) + return targets_list + + def get_new_sources(self, mapper): + if mapper is None: + return [] + + targets_list = [] + for node in mapper.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_NEW_SOURCES_TAG: + targets_xml = node + for node in targets_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == BD_TYPE: + targets_list.append(node)#.cloneNode(True)) + return targets_list + + def get_mapper_props(self, mapper): + if mapper is None: + return None + + props = None + for node in mapper.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props = node#.cloneNode(True) + if props is None: + raise Exception, 'mapper missing properties tag' + return props + + def get_target(self, mapper_id, path): + mapper = self.get_mapper(mapper_id) + if mapper is None: + return None + + targets = self.get_targets(mapper) + for t_xml in targets: + if t_xml.getAttribute('path') == path: + return t_xml#.cloneNode(True) + return None def is_storage_report_cached(session, storagename): - if session.has_key(SESSION_STORAGE_XML_REPORT): - reports_dir = session[SESSION_STORAGE_XML_REPORT] - if reports_dir.has_key(storagename): - if reports_dir[storagename] is not None: - return True - return False + if session.has_key(SESSION_STORAGE_XML_REPORT): + reports_dir = session[SESSION_STORAGE_XML_REPORT] + if reports_dir.has_key(storagename): + if reports_dir[storagename] is not None: + return True + return False def invalidate_storage_report(session, storagename): - reports_dir = {} - if session.has_key(SESSION_STORAGE_XML_REPORT): - reports_dir = session[SESSION_STORAGE_XML_REPORT] - reports_dir[storagename] = None - session.set(SESSION_STORAGE_XML_REPORT, reports_dir) - return + reports_dir = {} + if session.has_key(SESSION_STORAGE_XML_REPORT): + reports_dir = session[SESSION_STORAGE_XML_REPORT] + reports_dir[storagename] = None + session.set(SESSION_STORAGE_XML_REPORT, reports_dir) + return def cache_storage_report(ricci_comm, session): - try: - rep = get_storage_report(ricci_comm, session) - if rep is None: - raise Exception, 'Unable to communicate with host (either system down or ricci not running on it)' - else: - return True - except Exception, e: - return str(e) - except: - return 'Luci internal error. Please file bug report.' - return 'should never come here' + try: + rep = get_storage_report(ricci_comm, session) + if rep is None: + raise Exception, 'Unable to communicate with host (either system down or ricci not running on it)' + else: + return True + except Exception, e: + return str(e) + except: + return 'Luci internal error. Please file bug report.' + return 'should never come here' def get_storage_report(ricci_comm, session): - if ricci_comm is None: - return None + if ricci_comm is None: + return None - storagename = ricci_comm.hostname() + storagename = ricci_comm.hostname() - # setup cache, if not already set up - if not session.has_key(SESSION_STORAGE_XML_REPORT): - session.set(SESSION_STORAGE_XML_REPORT, {}) - # return cached report if existing - if session[SESSION_STORAGE_XML_REPORT].has_key(storagename): - tmp_report = session[SESSION_STORAGE_XML_REPORT][storagename] - if tmp_report is not None: - return StorageReport(tmp_report) - - - # request - doc = minidom.Document() - batch = doc.createElement('batch') - module = doc.createElement('module') - module.setAttribute('name', 'storage') - request = doc.createElement('request') - request.setAttribute('API_version', '1.0') - function = doc.createElement('function_call') - function.setAttribute('name', 'report') - batch.appendChild(module) - module.appendChild(request) - request.appendChild(function) - - # get report - batch_r = ricci_comm.process_batch(batch) - if batch_r.getAttribute('status') != '0': - #raise Exception, 'error retrieving storage report' - # dig deeper to find causing error - pass - module_r = None - for node in batch_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'module': - module_r = node - if module_r is None: - raise Exception, 'malformed response: missing in ' - module_r_status = module_r.getAttribute('status') - if module_r_status != '0': - #raise Exception, 'error retrieving storage report' - if module_r_status == '3': - raise Exception, 'Unable to find storage module on host (reinstall it)' - resp_r = None - for node in module_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'response': - resp_r = node - if resp_r is None: - raise Exception, 'malformed response: missing in ' - fr_r = None - for node in resp_r.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'function_response': - fr_r = node - if fr_r is None: - raise Exception, 'malformed response: missing in ' - succ_v = None - err_code_v = None - err_desc_v = None - for node in fr_r.childNodes: - try: - var = parse_variable(node) - if var.get_name() == 'success': - succ_v = var - elif var.get_name() == 'error_code': - err_code_v = var - elif var.get_name() == 'error_description': - err_desc_v = var - except: - pass - if succ_v is None: - raise Exception, 'malformed response: missing "success" variable in ' - if succ_v.get_value() is not True: - # error - if err_code_v.get_value() == -1: - raise Exception, 'Generic error on host:\n\n%s' % err_desc_v.get_value() - else: - raise Exception, 'Host responded: %s' % err_desc_v.get_value() - - xml_report = fr_r - - # cache xml_report - reports_dir = session[SESSION_STORAGE_XML_REPORT] - reports_dir[storagename] = xml_report - session.set(SESSION_STORAGE_XML_REPORT, reports_dir) + # setup cache, if not already set up + if not session.has_key(SESSION_STORAGE_XML_REPORT): + session.set(SESSION_STORAGE_XML_REPORT, {}) + # return cached report if existing + if session[SESSION_STORAGE_XML_REPORT].has_key(storagename): + tmp_report = session[SESSION_STORAGE_XML_REPORT][storagename] + if tmp_report is not None: + return StorageReport(tmp_report) + + # request + doc = minidom.Document() + batch = doc.createElement('batch') + module = doc.createElement('module') + module.setAttribute('name', 'storage') + request = doc.createElement('request') + request.setAttribute('API_version', '1.0') + function = doc.createElement('function_call') + function.setAttribute('name', 'report') + batch.appendChild(module) + module.appendChild(request) + request.appendChild(function) + + # get report + batch_r = ricci_comm.process_batch(batch) + if batch_r.getAttribute('status') != '0': + #raise Exception, 'error retrieving storage report' + # dig deeper to find causing error + pass + module_r = None + for node in batch_r.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'module': + module_r = node + if module_r is None: + raise Exception, 'malformed response: missing in ' + module_r_status = module_r.getAttribute('status') + if module_r_status != '0': + #raise Exception, 'error retrieving storage report' + if module_r_status == '3': + raise Exception, 'Unable to find storage module on host (reinstall it)' + resp_r = None + for node in module_r.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'response': + resp_r = node + if resp_r is None: + raise Exception, 'malformed response: missing in ' + fr_r = None + for node in resp_r.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'function_response': + fr_r = node + if fr_r is None: + raise Exception, 'malformed response: missing in ' + succ_v = None + err_code_v = None + err_desc_v = None + for node in fr_r.childNodes: + try: + var = parse_variable(node) + if var.get_name() == 'success': + succ_v = var + elif var.get_name() == 'error_code': + err_code_v = var + elif var.get_name() == 'error_description': + err_desc_v = var + except: + pass + if succ_v is None: + raise Exception, 'malformed response: missing "success" variable in ' + if succ_v.get_value() is not True: + # error + if err_code_v.get_value() == -1: + raise Exception, 'Generic error on host:\n\n%s' % err_desc_v.get_value() + else: + raise Exception, 'Host responded: %s' % err_desc_v.get_value() + + xml_report = fr_r + + # cache xml_report + reports_dir = session[SESSION_STORAGE_XML_REPORT] + reports_dir[storagename] = xml_report + session.set(SESSION_STORAGE_XML_REPORT, reports_dir) - return StorageReport(xml_report) + return StorageReport(xml_report) def get_content_data(self, storage_report, mapper_id, bd_path, content_id): - bd_data = get_bd_data(self, storage_report, mapper_id, bd_path) - for cont in bd_data['contents']: - if cont['id'] == content_id: - return cont - return None + bd_data = get_bd_data(self, storage_report, mapper_id, bd_path) + for cont in bd_data['contents']: + if cont['id'] == content_id: + return cont + return None def get_bd_data(self, storage_report, mapper_id, path): - if storage_report is None or mapper_id is None: - return None + if storage_report is None or mapper_id is None: + return None - mapper = get_mapper_data(self, storage_report, mapper_id) - if mapper is None: - return None - - for t in mapper['targets']: - if t['path'] == path: - return t - for t in mapper['new_targets']: - if t['path'] == path: - return t - if path == 'new_snapshot' and mapper['mapper_type'] == MAPPER_VG_TYPE: - return mapper['snapshot_template'] - return None + mapper = get_mapper_data(self, storage_report, mapper_id) + if mapper is None: + return None + + for t in mapper['targets']: + if t['path'] == path: + return t + for t in mapper['new_targets']: + if t['path'] == path: + return t + if path == 'new_snapshot' and mapper['mapper_type'] == MAPPER_VG_TYPE: + return mapper['snapshot_template'] + return None def get_mappers_data(self, storage_report): - ret_dir = {} - # mappers - mappers_dir = storage_report.get_mappers_dir() - for mapp_type in mappers_dir: - for m_xml in mappers_dir[mapp_type]: - mapper_id = m_xml.getAttribute('mapper_id') - if mapp_type not in ret_dir: - ret_dir[mapp_type] = {} - ret_dir[mapp_type]['mappers'] = [] - ret_dir[mapp_type]['mapper_template'] = None - ret_dir[mapp_type]['mappers'].append(get_mapper_data(self, storage_report, mapper_id)) - # templates - for mapp_type in storage_report.get_mapper_temps_dir(): - if mapp_type not in ret_dir: - ret_dir[mapp_type] = {} - ret_dir[mapp_type]['mappers'] = [] - ret_dir[mapp_type]['mapper_template'] = get_mapper_template_data(self, storage_report, mapp_type) - - # pretty stuff - for mapp_type in ret_dir: - info = ret_dir[mapp_type] - info_source = None - if len(info['mappers']) != 0: - info_source = info['mappers'][0] - else: - info_source = info['mapper_template'] - info['pretty_type'] = info_source['pretty_type'] - info['pretty_target_name'] = info_source['pretty_target_name'] - info['pretty_targets_name'] = info_source['pretty_targets_name'] - info['pretty_source_name'] = info_source['pretty_source_name'] - info['pretty_sources_name'] = info_source['pretty_sources_name'] + ret_dir = {} + # mappers + mappers_dir = storage_report.get_mappers_dir() + for mapp_type in mappers_dir: + for m_xml in mappers_dir[mapp_type]: + mapper_id = m_xml.getAttribute('mapper_id') + if mapp_type not in ret_dir: + ret_dir[mapp_type] = {} + ret_dir[mapp_type]['mappers'] = [] + ret_dir[mapp_type]['mapper_template'] = None + ret_dir[mapp_type]['mappers'].append(get_mapper_data(self, storage_report, mapper_id)) + # templates + for mapp_type in storage_report.get_mapper_temps_dir(): + if mapp_type not in ret_dir: + ret_dir[mapp_type] = {} + ret_dir[mapp_type]['mappers'] = [] + ret_dir[mapp_type]['mapper_template'] = get_mapper_template_data(self, storage_report, mapp_type) + + # pretty stuff + for mapp_type in ret_dir: + info = ret_dir[mapp_type] + info_source = None + if len(info['mappers']) != 0: + info_source = info['mappers'][0] + else: + info_source = info['mapper_template'] + info['pretty_type'] = info_source['pretty_type'] + info['pretty_target_name'] = info_source['pretty_target_name'] + info['pretty_targets_name'] = info_source['pretty_targets_name'] + info['pretty_source_name'] = info_source['pretty_source_name'] + info['pretty_sources_name'] = info_source['pretty_sources_name'] - return ret_dir + return ret_dir def get_mapper_data(self, storage_report, mapper_id): - if self is None or storage_report is None or mapper_id is None: - return None - - session = self.REQUEST.SESSION + if self is None or storage_report is None or mapper_id is None: + return None - mapper = storage_report.get_mapper(mapper_id) - if mapper is None: - return None - - removable, props = get_props_data_internal(session, mapper) - - new_targets = [] - for t_xml in storage_report.get_new_targets(mapper): - new_targets.append(get_bd_data_internal(session, t_xml, mapper)) - new_sources = [] - for s_xml in storage_report.get_new_sources(mapper): - new_sources.append(get_bd_data_internal(session, s_xml, mapper)) - targets = [] - for t_xml in storage_report.get_targets(mapper): - targets.append(get_bd_data_internal(session, t_xml, mapper)) - sources = [] - for s_xml in storage_report.get_sources(mapper): - sources.append(get_bd_data_internal(session, s_xml, mapper)) - - mapper_type = mapper.getAttribute('mapper_type') - pretty_type, pretty_target_name, pretty_source_name = get_pretty_mapper_info(mapper_type) - pretty_name = mapper_id.replace('%s:' % mapper_type, '').replace('/dev/', '') - pretty_targets_name = '%ss' % pretty_target_name - pretty_sources_name = '%ss' % pretty_source_name - icon_name, dummy1, dummy2 = get_mapper_icons(mapper_type) - color = 'black' - - mapper_ret = {} - mapper_ret['pretty_type'] = pretty_type - mapper_ret['pretty_name'] = pretty_name - mapper_ret['pretty_target_name'] = pretty_target_name - mapper_ret['pretty_targets_name'] = pretty_targets_name - mapper_ret['pretty_source_name'] = pretty_source_name - mapper_ret['pretty_sources_name'] = pretty_sources_name - mapper_ret['mapper_id'] = mapper_id - mapper_ret['mapper_type'] = mapper_type - mapper_ret['props'] = props - mapper_ret['props_ordered'] = get_ordered_props(props) - mapper_ret['targets'] = targets - mapper_ret['new_targets'] = new_targets - mapper_ret['sources'] = sources - mapper_ret['new_sources'] = new_sources - mapper_ret['icon'] = icon_name - mapper_ret['color'] = color - mapper_ret['xml'] = mapper#.cloneNode(True) - - assemble_all_targets(mapper_ret) - - actions = [] - if removable: - action = {'name' : 'Remove', - 'msg' : 'Are you sure you want to remove %s \\\'%s\\\'?' % (pretty_type, pretty_name), - 'link' : ''} - actions.append(action) - if mapper_type == MAPPER_VG_TYPE or mapper_type == MAPPER_MDRAID_TYPE or mapper_type == MAPPER_ATARAID_TYPE or mapper_type == MAPPER_MULTIPATH_TYPE: - action = {'name' : 'Add %s' % mapper_ret['pretty_sources_name'], - 'msg' : '', - 'link' : './?%s=%s&%s=%s&%s=%s' % (PAGETYPE, ADD_SOURCES, PT_MAPPER_ID, mapper_ret['mapper_id'], PT_MAPPER_TYPE, mapper_ret['mapper_type'])} - actions.append(action) - if mapper_type == MAPPER_VG_TYPE: - for nt in mapper_ret['new_targets']: - if nt['props']['snapshot']['value'] == 'false': - if nt['new']: - action = {'name' : 'New %s' % mapper_ret['pretty_target_name'], - 'msg' : '', - 'link' : './?%s=%s&%s=%s&%s=%s&%s=%s' \ - % (PAGETYPE, VIEW_BD, - PT_MAPPER_ID, mapper_ret['mapper_id'], \ - PT_MAPPER_TYPE, mapper_ret['mapper_type'], \ - PT_PATH, nt['path'])} - actions.append(action) - break - mapper_ret['actions'] = actions - - if mapper_type == MAPPER_VG_TYPE: - link_snapshots(mapper_ret) - - # cylinders work properly for VGs only, for now - mapper_ret['graphical_view'] = mapper_type != MAPPER_PT_TYPE - if mapper_ret['graphical_view']: - mapper_ret['mappings-view_css_classnames'] = {'graphical_view' : 'visible', - 'textual_view' : 'invisible'} - else: - mapper_ret['mappings-view_css_classnames'] = {'graphical_view' : 'invisible', - 'textual_view' : 'visible'} + session = self.REQUEST.SESSION - mapper_ret['need_apply_button'] = mutable_props(mapper_ret['props']) - - return mapper_ret + mapper = storage_report.get_mapper(mapper_id) + if mapper is None: + return None + + removable, props = get_props_data_internal(session, mapper) + + new_targets = [] + for t_xml in storage_report.get_new_targets(mapper): + new_targets.append(get_bd_data_internal(session, t_xml, mapper)) + + new_sources = [] + for s_xml in storage_report.get_new_sources(mapper): + new_sources.append(get_bd_data_internal(session, s_xml, mapper)) + + targets = [] + for t_xml in storage_report.get_targets(mapper): + targets.append(get_bd_data_internal(session, t_xml, mapper)) + + sources = [] + for s_xml in storage_report.get_sources(mapper): + sources.append(get_bd_data_internal(session, s_xml, mapper)) + + mapper_type = mapper.getAttribute('mapper_type') + pretty_type, pretty_target_name, pretty_source_name = get_pretty_mapper_info(mapper_type) + pretty_name = mapper_id.replace('%s:' % mapper_type, '').replace('/dev/', '') + pretty_targets_name = '%ss' % pretty_target_name + pretty_sources_name = '%ss' % pretty_source_name + icon_name, dummy1, dummy2 = get_mapper_icons(mapper_type) + color = 'black' + + mapper_ret = {} + mapper_ret['pretty_type'] = pretty_type + mapper_ret['pretty_name'] = pretty_name + mapper_ret['pretty_target_name'] = pretty_target_name + mapper_ret['pretty_targets_name'] = pretty_targets_name + mapper_ret['pretty_source_name'] = pretty_source_name + mapper_ret['pretty_sources_name'] = pretty_sources_name + mapper_ret['mapper_id'] = mapper_id + mapper_ret['mapper_type'] = mapper_type + mapper_ret['props'] = props + mapper_ret['props_ordered'] = get_ordered_props(props) + mapper_ret['targets'] = targets + mapper_ret['new_targets'] = new_targets + mapper_ret['sources'] = sources + mapper_ret['new_sources'] = new_sources + mapper_ret['icon'] = icon_name + mapper_ret['color'] = color + mapper_ret['xml'] = mapper#.cloneNode(True) + + assemble_all_targets(mapper_ret) + + actions = [] + if removable: + action = { + 'name': 'Remove', + 'msg': 'Are you sure you want to remove %s \\\'%s\\\'?' % (pretty_type, pretty_name), + 'link': '' + } + actions.append(action) + if mapper_type == MAPPER_VG_TYPE or mapper_type == MAPPER_MDRAID_TYPE or mapper_type == MAPPER_ATARAID_TYPE or mapper_type == MAPPER_MULTIPATH_TYPE: + action = { + 'name': 'Add %s' % mapper_ret['pretty_sources_name'], + 'msg': '', + 'link': './?%s=%s&%s=%s&%s=%s' \ + % (PAGETYPE, ADD_SOURCES, PT_MAPPER_ID, mapper_ret['mapper_id'], PT_MAPPER_TYPE, mapper_ret['mapper_type']) + } + actions.append(action) + if mapper_type == MAPPER_VG_TYPE: + for nt in mapper_ret['new_targets']: + if nt['props']['snapshot']['value'] == 'false': + if nt['new']: + action = { + 'name': 'New %s' % mapper_ret['pretty_target_name'], + 'msg': '', + 'link': './?%s=%s&%s=%s&%s=%s&%s=%s' \ + % (PAGETYPE, VIEW_BD, + PT_MAPPER_ID, mapper_ret['mapper_id'], \ + PT_MAPPER_TYPE, mapper_ret['mapper_type'], \ + PT_PATH, nt['path']) + } + actions.append(action) + break + mapper_ret['actions'] = actions + + if mapper_type == MAPPER_VG_TYPE: + link_snapshots(mapper_ret) + + # cylinders work properly for VGs only, for now + mapper_ret['graphical_view'] = mapper_type != MAPPER_PT_TYPE + if mapper_ret['graphical_view']: + mapper_ret['mappings-view_css_classnames'] = { + 'graphical_view': 'visible', + 'textual_view': 'invisible' + } + else: + mapper_ret['mappings-view_css_classnames'] = { + 'graphical_view': 'invisible', + 'textual_view': 'visible' + } + mapper_ret['need_apply_button'] = mutable_props(mapper_ret['props']) + return mapper_ret def link_snapshots(mapper): - for snap in mapper['targets']: - if snap['props']['snapshot']['value'] != 'true': - continue - orig_name = snap['props']['snapshot_origin']['value'] - snap['description'] = '%s, %s\'s Snapshot' \ - % (snap['description'], orig_name) - - # find origin - for t in mapper['targets']: - if t['pretty_name'] == orig_name: - if 'snapshots' not in t: - t['snapshots'] = [] - snap['origin'] = t - t['snapshots'].append(snap) - return - - + for snap in mapper['targets']: + if snap['props']['snapshot']['value'] != 'true': + continue + orig_name = snap['props']['snapshot_origin']['value'] + snap['description'] = '%s, %s\'s Snapshot' \ + % (snap['description'], orig_name) + + # find origin + for t in mapper['targets']: + if t['pretty_name'] == orig_name: + if 'snapshots' not in t: + t['snapshots'] = [] + snap['origin'] = t + t['snapshots'].append(snap) + return def assemble_all_targets(mapper_data): - mdata = mapper_data - targets_all = [] + mdata = mapper_data + targets_all = [] - if mdata['mapper_type'] == MAPPER_VG_TYPE: - for t in mdata['targets']: - targets_all.append(t) - for t in mdata['new_targets']: - if t['props']['snapshot']['value'] == 'false': - targets_all.append(t) - else: - mdata['snapshot_template'] = t - elif mdata['mapper_type'] == MAPPER_PT_TYPE: - # extended-primary substitution - extended_templs = [] - for t in mdata['new_targets']: - if t['props']['partition_type']['value'] == 'extended': - extended_templs.append(t) - for ext in extended_templs: - # find matching primary parts - for t in mdata['new_targets']: - if t['props']['partition_type']['value'] == 'primary': - if t['props']['partition_begin']['value'] == ext['props']['partition_begin']['value']: - t['props']['partition_type']['replacements'] = {'repl_names' : ['primary', 'extended'], - 'primary' : t, - 'extended' : ext } - ext['props']['partition_type']['replacements'] = {'repl_names' : ['extended', 'primary'], - 'extended' : ext, - 'primary' : t } - for t in mdata['targets']: - targets_all.append(t) - for t in mdata['new_targets']: - if t['props']['partition_type']['value'] != 'extended': - targets_all.append(t) - - # TODO: place logical into extended - - # sort partitions - p_sorted = [] - while len(targets_all) != 0: - smallest_num = 100000000000000000000 - smallest_bd = None - smallest_index = 0 - i = 0 - for i in xrange(len(targets_all)): - bd = targets_all[i] - begin = int(bd['props']['partition_begin']['value']) - if begin < smallest_num: - smallest_num = begin - smallest_bd = bd - smallest_index = i - targets_all.pop(smallest_index) - p_sorted.append(smallest_bd) - targets_all = p_sorted - else: - for t in mdata['targets']: - targets_all.append(t) - for t in mdata['new_targets']: - targets_all.append(t) + if mdata['mapper_type'] == MAPPER_VG_TYPE: + for t in mdata['targets']: + targets_all.append(t) + for t in mdata['new_targets']: + if t['props']['snapshot']['value'] == 'false': + targets_all.append(t) + else: + mdata['snapshot_template'] = t + elif mdata['mapper_type'] == MAPPER_PT_TYPE: + # extended-primary substitution + extended_templs = [] + for t in mdata['new_targets']: + if t['props']['partition_type']['value'] == 'extended': + extended_templs.append(t) + for ext in extended_templs: + # find matching primary parts + for t in mdata['new_targets']: + if t['props']['partition_type']['value'] == 'primary': + if t['props']['partition_begin']['value'] == ext['props']['partition_begin']['value']: + t['props']['partition_type']['replacements'] = { + 'repl_names': ['primary', 'extended'], + 'primary': t, + 'extended': ext + } + + ext['props']['partition_type']['replacements'] = { + 'repl_names': ['extended', 'primary'], + 'extended': ext, + 'primary': t + } + for t in mdata['targets']: + targets_all.append(t) + for t in mdata['new_targets']: + if t['props']['partition_type']['value'] != 'extended': + targets_all.append(t) + + # TODO: place logical into extended + + # sort partitions + p_sorted = [] + while len(targets_all) != 0: + smallest_num = 100000000000000000000 + smallest_bd = None + smallest_index = 0 + i = 0 + for i in xrange(len(targets_all)): + bd = targets_all[i] + begin = int(bd['props']['partition_begin']['value']) + if begin < smallest_num: + smallest_num = begin + smallest_bd = bd + smallest_index = i + targets_all.pop(smallest_index) + p_sorted.append(smallest_bd) + targets_all = p_sorted + else: + for t in mdata['targets']: + targets_all.append(t) + for t in mdata['new_targets']: + targets_all.append(t) - mdata['targets_all'] = targets_all + mdata['targets_all'] = targets_all def get_mapper_template_data(self, storage_report, mapper_type): - if self is None or storage_report is None or mapper_type is None: - return None - - session = self.REQUEST.SESSION - - mapper_id = '' - - templ_xml_list = storage_report.get_mapper_temps(mapper_type) - mapper = None - if len(templ_xml_list) != 0: - mapper = templ_xml_list[0] - if mapper is None: - return None - - removable, props = get_props_data_internal(session, mapper) - - new_targets = [] - for t_xml in storage_report.get_new_targets(mapper): - new_targets.append(get_bd_data_internal(session, t_xml, mapper)) - new_sources = [] - for s_xml in storage_report.get_new_sources(mapper): - new_sources.append(get_bd_data_internal(session, s_xml, mapper)) - targets = [] - for t_xml in storage_report.get_targets(mapper): - targets.append(get_bd_data_internal(session, t_xml, mapper)) - sources = [] - for s_xml in storage_report.get_sources(mapper): - sources.append(get_bd_data_internal(session, s_xml, mapper)) - - mapper_type = mapper.getAttribute('mapper_type') - pretty_type, pretty_target_name, pretty_source_name = get_pretty_mapper_info(mapper_type) - pretty_name = mapper_id.replace('%s:' % mapper_type, '').replace('/dev/', '') - pretty_targets_name = '%ss' % pretty_target_name - pretty_sources_name = '%ss' % pretty_source_name - icon_name, dummy1, dummy2 = get_mapper_icons(mapper_type) - color = 'black' - - min_sources = '0' - max_sources = '0' - new_props = {} - for name in props: - if name == 'min_sources': - min_sources = props[name]['value'] - elif name == 'max_sources': - max_sources = props[name]['value'] - else: - new_props[name] = props[name] - props = new_props - - mapper_ret = {} - mapper_ret['pretty_type'] = pretty_type - mapper_ret['pretty_name'] = pretty_name - mapper_ret['pretty_target_name'] = pretty_target_name - mapper_ret['pretty_targets_name'] = pretty_targets_name - mapper_ret['pretty_source_name'] = pretty_source_name - mapper_ret['pretty_sources_name'] = pretty_sources_name - mapper_ret['mapper_id'] = mapper_id - mapper_ret['mapper_type'] = mapper_type - mapper_ret['props'] = props - mapper_ret['props_ordered'] = get_ordered_props(props) - #mapper_ret['removable'] = removable - mapper_ret['targets'] = targets - mapper_ret['new_targets'] = new_targets - mapper_ret['sources'] = sources - mapper_ret['new_sources'] = new_sources - mapper_ret['min_sources'] = min_sources - mapper_ret['max_sources'] = max_sources - mapper_ret['icon'] = icon_name - mapper_ret['color'] = color - mapper_ret['xml'] = mapper#.cloneNode(True) - - mapper_ret['actions'] = [] - - mapper_ret['need_apply_button'] = True - - return mapper_ret - - + if self is None or storage_report is None or mapper_type is None: + return None + session = self.REQUEST.SESSION + mapper_id = '' + templ_xml_list = storage_report.get_mapper_temps(mapper_type) + mapper = None + + if len(templ_xml_list) != 0: + mapper = templ_xml_list[0] + + if mapper is None: + return None + + removable, props = get_props_data_internal(session, mapper) + + new_targets = [] + for t_xml in storage_report.get_new_targets(mapper): + new_targets.append(get_bd_data_internal(session, t_xml, mapper)) + + new_sources = [] + for s_xml in storage_report.get_new_sources(mapper): + new_sources.append(get_bd_data_internal(session, s_xml, mapper)) + + targets = [] + for t_xml in storage_report.get_targets(mapper): + targets.append(get_bd_data_internal(session, t_xml, mapper)) + + sources = [] + for s_xml in storage_report.get_sources(mapper): + sources.append(get_bd_data_internal(session, s_xml, mapper)) + + mapper_type = mapper.getAttribute('mapper_type') + pretty_type, pretty_target_name, pretty_source_name = get_pretty_mapper_info(mapper_type) + pretty_name = mapper_id.replace('%s:' % mapper_type, '').replace('/dev/', '') + pretty_targets_name = '%ss' % pretty_target_name + pretty_sources_name = '%ss' % pretty_source_name + icon_name, dummy1, dummy2 = get_mapper_icons(mapper_type) + color = 'black' + + min_sources = '0' + max_sources = '0' + new_props = {} + for name in props: + if name == 'min_sources': + min_sources = props[name]['value'] + elif name == 'max_sources': + max_sources = props[name]['value'] + else: + new_props[name] = props[name] + props = new_props + + mapper_ret = {} + mapper_ret['pretty_type'] = pretty_type + mapper_ret['pretty_name'] = pretty_name + mapper_ret['pretty_target_name'] = pretty_target_name + mapper_ret['pretty_targets_name'] = pretty_targets_name + mapper_ret['pretty_source_name'] = pretty_source_name + mapper_ret['pretty_sources_name'] = pretty_sources_name + mapper_ret['mapper_id'] = mapper_id + mapper_ret['mapper_type'] = mapper_type + mapper_ret['props'] = props + mapper_ret['props_ordered'] = get_ordered_props(props) + #mapper_ret['removable'] = removable + mapper_ret['targets'] = targets + mapper_ret['new_targets'] = new_targets + mapper_ret['sources'] = sources + mapper_ret['new_sources'] = new_sources + mapper_ret['min_sources'] = min_sources + mapper_ret['max_sources'] = max_sources + mapper_ret['icon'] = icon_name + mapper_ret['color'] = color + mapper_ret['xml'] = mapper#.cloneNode(True) + + mapper_ret['actions'] = [] + mapper_ret['need_apply_button'] = True + return mapper_ret # TODO: implement def validate(self, storage_report, request): - #return 'size has to be within limits' - #return request - #return 'OK' - - object_type = request['object_type'] - mapper_id = request['mapper_id'] - - props = None - content_props = None - - if object_type == 'bd' or object_type == 'bd_template': - path = request[PT_PATH] - bd_data = get_bd_data(self, storage_report, mapper_id, path) - props = bd_data['props'] - if path != 'new_snapshot': - selected_content_id = request['content_id'] - for c_data in bd_data['contents']: - if c_data['id'] == selected_content_id: - content_props = c_data['props'] - elif object_type == 'mapper': - props = get_mapper_data(self, storage_report, mapper_id)['props'] - elif object_type == 'mapper_template': - mapper_type = request['mapper_type'] - data = get_mapper_template_data(self, storage_report, mapper_type) - # find sources - sources_num = 0 - for v in request.keys(): - if v.find('source_bd_') == 0: - if request[v] == 'on': - sources_num += 1 - if sources_num < int(data['min_sources']) or sources_num > int(data['max_sources']): - return 'BAD: Invalid number of %s selected' % data['pretty_sources_name'] - props = data['props'] - elif object_type == 'add_sources': - data = get_mapper_data(self, storage_report, mapper_id) - # find sources - sources_num = 0 - for v in request.keys(): - if v.find('source_bd_') == 0: - if request[v] == 'on': - sources_num += 1 - if sources_num == 0 or sources_num > len(data['new_sources']): - return 'BAD: Invalid number of %s selected' % data['pretty_sources_name'] - - if props is not None: - res = check_props(self, props, request) - if res[0] is False: - return '%s %s' % (res[1], res[2]) - - if content_props is not None: - res = check_props(self, content_props, request) - if res[0] is False: - return '%s %s' % (res[1], res[2]) + #return 'size has to be within limits' + #return request + #return 'OK' + + object_type = request['object_type'] + mapper_id = request['mapper_id'] + + props = None + content_props = None + + if object_type == 'bd' or object_type == 'bd_template': + path = request[PT_PATH] + bd_data = get_bd_data(self, storage_report, mapper_id, path) + props = bd_data['props'] + if path != 'new_snapshot': + selected_content_id = request['content_id'] + for c_data in bd_data['contents']: + if c_data['id'] == selected_content_id: + content_props = c_data['props'] + elif object_type == 'mapper': + props = get_mapper_data(self, storage_report, mapper_id)['props'] + elif object_type == 'mapper_template': + mapper_type = request['mapper_type'] + data = get_mapper_template_data(self, storage_report, mapper_type) + # find sources + sources_num = 0 + for v in request.keys(): + if v.find('source_bd_') == 0: + if request[v] == 'on': + sources_num += 1 + if sources_num < int(data['min_sources']) or sources_num > int(data['max_sources']): + return 'BAD: Invalid number of %s selected' % data['pretty_sources_name'] + props = data['props'] + elif object_type == 'add_sources': + data = get_mapper_data(self, storage_report, mapper_id) + # find sources + sources_num = 0 + for v in request.keys(): + if v.find('source_bd_') == 0: + if request[v] == 'on': + sources_num += 1 + if sources_num == 0 or sources_num > len(data['new_sources']): + return 'BAD: Invalid number of %s selected' % data['pretty_sources_name'] + + if props is not None: + res = check_props(self, props, request) + if res[0] is False: + return '%s %s' % (res[1], res[2]) + + if content_props is not None: + res = check_props(self, content_props, request) + if res[0] is False: + return '%s %s' % (res[1], res[2]) - return 'OK' + return 'OK' def check_props(self, props, request): - valid = True - var_name = '' - msg = 'no message - BUG' - - for prop_name in props: - if prop_name in request: - prop = props[prop_name] - req_value = request[prop_name] - if prop['type'] == 'int': - if prop['units'] != 'bytes': - try: - req_value = int(req_value) - except: - msg = '%s is missing an integer value' % prop['pretty_name'] - var_name = prop_name - valid = False - break - min_val = int(prop['validation']['min']) - max_val = int(prop['validation']['max']) - step = int(prop['validation']['step']) - r_val = (req_value / step) * step - if r_val > max_val or r_val < min_val: - msg = '%s has to be within range %d-%d %s' \ - % (prop['pretty_name'], min_val, max_val, prop['units']) - var_name = prop_name - valid = False - break - else: - try: - req_value = float(req_value) - except: - msg = '%s is missing a float value' % prop['pretty_name'] - var_name = prop_name - valid = False - break - dummy, units = bytes_to_value_prefunits(self, prop['value']) - min_val = float(convert_bytes(prop['validation']['min'], units)) - max_val = float(convert_bytes(prop['validation']['max'], units)) - step = float(convert_bytes(prop['validation']['step'], units)) - if step < 0.000001: - step = 0.000001 - r_val = (req_value / step) * step - if r_val > max_val or r_val < min_val: - msg = '%s has to be within range %d-%d %s' \ - % (prop['pretty_name'], min_val, max_val, units) - var_name = prop_name - valid = False - break - elif prop['type'] == 'text': - if len(req_value) < int(prop['validation']['min_length']): - msg = '%s has to have minimum length of %s' \ - % (prop['pretty_name'], prop['validation']['min_length']) - var_name = prop_name - valid = False - break - elif len(req_value) > int(prop['validation']['max_length']): - msg = '%s has to have maximum length of %s' \ - % (prop['pretty_name'], prop['validation']['max_length']) - var_name = prop_name - valid = False - break - elif req_value in prop['validation']['reserved_words'].split(';') and req_value != '': - msg = '%s contains reserved keyword. \nReserved keywords are %s' % (prop['pretty_name'], prop['validation']['reserved_words'].replace(';', ', ')) - var_name = prop_name - valid = False - break - # check illegal chars - for ch in prop['validation']['illegal_chars']: - if ch in req_value and ch != '': - msg = '%s contains illegal characters. \nIllegal characters are %s' % (prop['pretty_name'], prop['validation']['illegal_chars'].replace(';', ', ')) - var_name = prop_name - valid = False - break + valid = True + var_name = '' + msg = 'no message - BUG' + + for prop_name in props: + if prop_name in request: + prop = props[prop_name] + req_value = request[prop_name] + if prop['type'] == 'int': + if prop['units'] != 'bytes': + try: + req_value = int(req_value) + except: + msg = '%s is missing an integer value' % prop['pretty_name'] + var_name = prop_name + valid = False + break + min_val = int(prop['validation']['min']) + max_val = int(prop['validation']['max']) + step = int(prop['validation']['step']) + r_val = (req_value / step) * step + if r_val > max_val or r_val < min_val: + msg = '%s has to be within range %d-%d %s' \ + % (prop['pretty_name'], min_val, max_val, prop['units']) + var_name = prop_name + valid = False + break + else: + try: + req_value = float(req_value) + except: + msg = '%s is missing a float value' % prop['pretty_name'] + var_name = prop_name + valid = False + break + dummy, units = bytes_to_value_prefunits(self, prop['value']) + min_val = float(convert_bytes(prop['validation']['min'], units)) + max_val = float(convert_bytes(prop['validation']['max'], units)) + step = float(convert_bytes(prop['validation']['step'], units)) + if step < 0.000001: + step = 0.000001 + r_val = (req_value / step) * step + if r_val > max_val or r_val < min_val: + msg = '%s has to be within range %d-%d %s' \ + % (prop['pretty_name'], min_val, max_val, units) + var_name = prop_name + valid = False + break + elif prop['type'] == 'text': + if len(req_value) < int(prop['validation']['min_length']): + msg = '%s has to have minimum length of %s' \ + % (prop['pretty_name'], prop['validation']['min_length']) + var_name = prop_name + valid = False + break + elif len(req_value) > int(prop['validation']['max_length']): + msg = '%s has to have maximum length of %s' \ + % (prop['pretty_name'], prop['validation']['max_length']) + var_name = prop_name + valid = False + break + elif req_value in prop['validation']['reserved_words'].split(';') and req_value != '': + msg = '%s contains reserved keyword. \nReserved keywords are %s' % (prop['pretty_name'], prop['validation']['reserved_words'].replace(';', ', ')) + var_name = prop_name + valid = False + break + # check illegal chars + for ch in prop['validation']['illegal_chars']: + if ch in req_value and ch != '': + msg = '%s contains illegal characters. \nIllegal characters are %s' \ + % (prop['pretty_name'], prop['validation']['illegal_chars'].replace(';', ', ')) + var_name = prop_name + valid = False + break - return [valid, var_name, msg] + return [valid, var_name, msg] def apply_storage_changes(self, ricci, storage_report, request): - if validate(self, storage_report, request) != 'OK': - raise Exception, 'Internal error: input not validated!!!' - - session = request.SESSION - - storagename = request['storagename'] - - object_type = request['object_type'] - mapper_id = request[PT_MAPPER_ID] - mapper_type = request[PT_MAPPER_TYPE] - action_type = request['action_type'] - path = '' - if request.has_key(PT_PATH): - 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) - - if action_type == 'Remove': - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'remove_bd') - #f_call.appendChild(Variable('bd', bd_xml.cloneNode(True)).export_xml(doc)) - f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - elif action_type == 'Apply': - # BD props - props_xml = None - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - if var_name in request: - if bd_data['props'][var_name]['type'] == 'int': - if bd_data['props'][var_name]['units'] != 'bytes': - val = int(request[var_name]) - step = int(bd_data['props'][var_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - bd_data['props'][var_name]['value']) - min_val = int(bd_data['props'][var_name]['validation']['min']) - max_val = int(bd_data['props'][var_name]['validation']['max']) - step = int(bd_data['props'][var_name]['validation']['step']) - val_units = float(request[var_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[var_name]) - - # content - content_data_list = get_content_data_internal(session, bd_xml) - current_content_id = content_data_list[0]['id'] - selected_content_id = request['content_id'] - selected_content = None - selected_content_data = None - for c_data in content_data_list: - if c_data['id'] == selected_content_id: - selected_content_data = c_data - selected_content = c_data['xml']#.cloneNode(True) - - # update selected_content props - props_xml = None - for node in selected_content.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - req_name = 'content_variable_%s_%s' % (selected_content_id, var_name) - if req_name in request: - if selected_content_data['props'][req_name]['type'] == 'int': - if selected_content_data['props'][req_name]['units'] != 'bytes': - val = int(request[req_name]) - step = int(selected_content_data['props'][req_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - selected_content_data['props'][req_name]['value']) - min_val = int(selected_content_data['props'][req_name]['validation']['min']) - max_val = int(selected_content_data['props'][req_name]['validation']['max']) - step = int(selected_content_data['props'][req_name]['validation']['step']) - val_units = float(request[req_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[req_name]) - - if current_content_id == selected_content_id: - # no change of content - # replace content_xml - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'content': - bd_xml.removeChild(node) - bd_xml.appendChild(selected_content) - break - else: - # content changed - # place it under - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'content': - for node2 in node.childNodes: - if node2.nodeType == xml.dom.Node.ELEMENT_NODE: - if node2.nodeName == 'new_content': - node2.appendChild(selected_content) - break - #return bd_xml.toprettyxml() - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'modify_bd') - f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - elif object_type == 'bd_template': - path = request[PT_PATH] - bd_data = get_bd_data(self, storage_report, mapper_id, path) - bd_xml = bd_data['xml']#.cloneNode(True) - #return bd_xml.toprettyxml() - - if action_type == 'Apply': # Create - # BD props - props_xml = None - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - if var_name in request: - if bd_data['props'][var_name]['type'] == 'int': - if bd_data['props'][var_name]['units'] != 'bytes': - val = int(request[var_name]) - step = int(bd_data['props'][var_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - bd_data['props'][var_name]['value']) - min_val = int(bd_data['props'][var_name]['validation']['min']) - max_val = int(bd_data['props'][var_name]['validation']['max']) - step = int(bd_data['props'][var_name]['validation']['step']) - val_units = float(request[var_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[var_name]) - - if path != 'new_snapshot': - # content - content_data_list = get_content_data_internal(session, bd_xml) - current_content_id = content_data_list[0]['id'] - selected_content_id = request['content_id'] - selected_content = None - selected_content_data = None - for c_data in content_data_list: - if c_data['id'] == selected_content_id: - selected_content_data = c_data - selected_content = c_data['xml']#.cloneNode(True) - - # update selected_content props - props_xml = None - for node in selected_content.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - req_name = 'content_variable_%s_%s' % (selected_content_id, var_name) - if req_name in request: - if selected_content_data['props'][req_name]['type'] == 'int': - if selected_content_data['props'][req_name]['units'] != 'bytes': - val = int(request[req_name]) - step = int(selected_content_data['props'][req_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - selected_content_data['props'][req_name]['value']) - min_val = int(selected_content_data['props'][req_name]['validation']['min']) - max_val = int(selected_content_data['props'][req_name]['validation']['max']) - step = int(selected_content_data['props'][req_name]['validation']['step']) - val_units = float(request[req_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[req_name]) - - if current_content_id == selected_content_id: - # no change of content - # replace content_xml - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'content': - bd_xml.removeChild(node) - bd_xml.appendChild(selected_content) - break - else: - # content changed - # place it under - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == 'content': - for node2 in node.childNodes: - if node2.nodeType == xml.dom.Node.ELEMENT_NODE: - if node2.nodeName == 'new_content': - node2.appendChild(selected_content) - break - #return bd_xml.toprettyxml() - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'create_bd') - f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - - elif object_type == 'mapper': - mapper_data = get_mapper_data(self, storage_report, mapper_id) - mapper_xml = mapper_data['xml']#.cloneNode(True) - #return mapper_xml.toprettyxml() - - if action_type == 'Remove': - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'remove_mapper') - f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - elif action_type == 'Apply': - # props - props_xml = None - for node in mapper_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - if var_name in request: - if mapper_data['props'][var_name]['type'] == 'int': - if mapper_data['props'][var_name]['units'] != 'bytes': - val = int(request[var_name]) - step = int(mapper_data['props'][var_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - mapper_data['props'][var_name]['value']) - min_val = int(mapper_data['props'][var_name]['validation']['min']) - max_val = int(mapper_data['props'][var_name]['validation']['max']) - step = int(mapper_data['props'][var_name]['validation']['step']) - val_units = float(request[var_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[var_name]) - #return mapper_xml.toprettyxml() - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'modify_mapper') - f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - - elif object_type == 'mapper_template': - mapper_data = get_mapper_template_data(self, storage_report, mapper_type) - mapper_xml = mapper_data['xml']#.cloneNode(True) - #return mapper_xml.toprettyxml() - - if action_type == 'Apply': - # props - props_xml = None - for node in mapper_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - if node.getAttribute('mutable') == 'true': - var_name = node.getAttribute('name') - if request.has_key(var_name): - if mapper_data['props'][var_name]['type'] == 'int': - if mapper_data['props'][var_name]['units'] != 'bytes': - val = int(request[var_name]) - step = int(mapper_data['props'][var_name]['validation']['step']) - val = (val / step) * step - else: - dummy, units = bytes_to_value_prefunits(self, - mapper_data['props'][var_name]['value']) - min_val = int(mapper_data['props'][var_name]['validation']['min']) - max_val = int(mapper_data['props'][var_name]['validation']['max']) - step = int(mapper_data['props'][var_name]['validation']['step']) - val_units = float(request[var_name]) - val = int(val_units * get_units_multiplier(units)) - val = (val / step) * step - if val < min_val: - val = min_val - if val > max_val: - val = max_val - node.setAttribute('value', str(val)) - else: - node.setAttribute('value', request[var_name]) - - # find sources - for v in request.keys(): - if v.find('source_bd_') == 0: - if request[v] == 'on': - path = v[len('source_bd_'):] - for s_xml in storage_report.get_new_sources(mapper_xml): - if s_xml.getAttribute('path') == path: - for node in mapper_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_SOURCES_TAG: - node.appendChild(s_xml)#.cloneNode(True)) - #return mapper_xml.toprettyxml() - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "10") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'create_mapper') -# f_call.appendChild(Variable('mapper', mapper_xml.cloneNode(True)).export_xml(doc)) - f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - - - elif object_type == 'add_sources': - mapper_data = get_mapper_data(self, storage_report, mapper_id) - mapper_xml = mapper_data['xml']#.cloneNode(True) - new_sources = [] - #return mapper_xml.toprettyxml() - - if action_type == 'Apply': - # find sources - for v in request.keys(): - if v.find('source_bd_') == 0: - if request[v] == 'on': - path = v[len('source_bd_'):] - for ns in mapper_data['new_sources']: - if ns['path'] == path: - new_sources.append(ns['xml'])#.cloneNode(True)) - #return mapper_xml.toprettyxml() - doc = minidom.Document() - batch = doc.createElement("batch") - module = doc.createElement("module") - module.setAttribute("name", "storage") - req = doc.createElement("request") - req.setAttribute("API_version", "1.0") - req.setAttribute("sequence", "11") - f_call = doc.createElement("function_call") - f_call.setAttribute('name', 'add_mapper_sources') - f_call.appendChild(Variable('mapper_type', mapper_type).export_xml(doc)) - f_call.appendChild(Variable('mapper_id', mapper_id).export_xml(doc)) - f_call.appendChild(Variable('mapper_state_ind', mapper_xml.getAttribute('state_ind')).export_xml(doc)) - f_call.appendChild(VariableList('bds', new_sources, [], VARIABLE_TYPE_LIST_XML).export_xml(doc)) - - req.appendChild(f_call) - module.appendChild(req) - batch.appendChild(module) - - res = ricci.process_batch(batch, True) - batch_id = res.getAttribute('batch_id') - - - if batch_id == '': - raise Exception, '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 is None: - # ricci down - error = True - url = url - msg = 'Unable to contact %s' % 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 %s responded with error. No detailed info available.' % storagename - elif batch is None: - # no such batch - error = False - completed = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'No such batch' - else: - 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 = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Ricci on %s sent a malformed response' % storagename - 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 = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Ricci on %s removed request from scheduler. File bug report against ricci.' % storagename - elif code == -104: - # module failure - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Ricci on %s failed to execute storage module; reinstall it.' % storagename - elif code == -2: - # API error - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Luci server used invalid API to communicate with %s. File a bug report against luci.' % storagename - elif code == -1: - # undefined error - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Reason for failure (as reported by %s): %s' % (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 = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Mid-Air collision (storage on %s has changed since last probe).' % storagename - elif code == 2: - # validation error - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Validation error. File bug report against Luci.' - elif code == 3: - # unmount error - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Unmount failure: %s' % err_msg - elif code == 4: - # clvmd error - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'clvmd (clustered LVM daemon) is not running on %s' % storagename - elif code == 5: - # not quorate - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Cluster quorum is required, and yet cluster is not quorate. Start cluster, and try again.' - elif code == 6: - # LVM cluster locking not enabled - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'LVM cluster locking is not enabled on %s' % storagename - elif code == 7: - # cluster not running - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = 'Cluster infrastructure is not running on %s' % storagename - elif code > 8: - error = True - url = '%s?%s=%s&%s=%s' \ - % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) - msg = err_msg - - return {'error' : error, - 'completed' : completed, - 'redirect_url' : url, - 'msg' : msg} + if validate(self, storage_report, request) != 'OK': + raise Exception, 'Internal error: input not validated!!!' + session = request.SESSION + storagename = request['storagename'] + object_type = request['object_type'] + mapper_id = request[PT_MAPPER_ID] + mapper_type = request[PT_MAPPER_TYPE] + action_type = request['action_type'] + path = '' + if request.has_key(PT_PATH): + 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) + + if action_type == 'Remove': + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'remove_bd') + #f_call.appendChild(Variable('bd', bd_xml.cloneNode(True)).export_xml(doc)) + f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + elif action_type == 'Apply': + # BD props + props_xml = None + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + if var_name in request: + if bd_data['props'][var_name]['type'] == 'int': + if bd_data['props'][var_name]['units'] != 'bytes': + val = int(request[var_name]) + step = int(bd_data['props'][var_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + bd_data['props'][var_name]['value']) + min_val = int(bd_data['props'][var_name]['validation']['min']) + max_val = int(bd_data['props'][var_name]['validation']['max']) + step = int(bd_data['props'][var_name]['validation']['step']) + val_units = float(request[var_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[var_name]) + + # content + content_data_list = get_content_data_internal(session, bd_xml) + current_content_id = content_data_list[0]['id'] + selected_content_id = request['content_id'] + selected_content = None + selected_content_data = None + for c_data in content_data_list: + if c_data['id'] == selected_content_id: + selected_content_data = c_data + selected_content = c_data['xml']#.cloneNode(True) + + # update selected_content props + props_xml = None + for node in selected_content.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + req_name = 'content_variable_%s_%s' % (selected_content_id, var_name) + if req_name in request: + if selected_content_data['props'][req_name]['type'] == 'int': + if selected_content_data['props'][req_name]['units'] != 'bytes': + val = int(request[req_name]) + step = int(selected_content_data['props'][req_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + selected_content_data['props'][req_name]['value']) + min_val = int(selected_content_data['props'][req_name]['validation']['min']) + max_val = int(selected_content_data['props'][req_name]['validation']['max']) + step = int(selected_content_data['props'][req_name]['validation']['step']) + val_units = float(request[req_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[req_name]) + + if current_content_id == selected_content_id: + # no change of content + # replace content_xml + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'content': + bd_xml.removeChild(node) + bd_xml.appendChild(selected_content) + break + else: + # content changed + # place it under + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'content': + for node2 in node.childNodes: + if node2.nodeType == xml.dom.Node.ELEMENT_NODE: + if node2.nodeName == 'new_content': + node2.appendChild(selected_content) + break + #return bd_xml.toprettyxml() + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'modify_bd') + f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + elif object_type == 'bd_template': + path = request[PT_PATH] + bd_data = get_bd_data(self, storage_report, mapper_id, path) + bd_xml = bd_data['xml']#.cloneNode(True) + #return bd_xml.toprettyxml() + + if action_type == 'Apply': # Create + # BD props + props_xml = None + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + if var_name in request: + if bd_data['props'][var_name]['type'] == 'int': + if bd_data['props'][var_name]['units'] != 'bytes': + val = int(request[var_name]) + step = int(bd_data['props'][var_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + bd_data['props'][var_name]['value']) + min_val = int(bd_data['props'][var_name]['validation']['min']) + max_val = int(bd_data['props'][var_name]['validation']['max']) + step = int(bd_data['props'][var_name]['validation']['step']) + val_units = float(request[var_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[var_name]) + + if path != 'new_snapshot': + # content + content_data_list = get_content_data_internal(session, bd_xml) + current_content_id = content_data_list[0]['id'] + selected_content_id = request['content_id'] + selected_content = None + selected_content_data = None + for c_data in content_data_list: + if c_data['id'] == selected_content_id: + selected_content_data = c_data + selected_content = c_data['xml']#.cloneNode(True) + + # update selected_content props + props_xml = None + for node in selected_content.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + req_name = 'content_variable_%s_%s' % (selected_content_id, var_name) + if req_name in request: + if selected_content_data['props'][req_name]['type'] == 'int': + if selected_content_data['props'][req_name]['units'] != 'bytes': + val = int(request[req_name]) + step = int(selected_content_data['props'][req_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + selected_content_data['props'][req_name]['value']) + min_val = int(selected_content_data['props'][req_name]['validation']['min']) + max_val = int(selected_content_data['props'][req_name]['validation']['max']) + step = int(selected_content_data['props'][req_name]['validation']['step']) + val_units = float(request[req_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[req_name]) + + if current_content_id == selected_content_id: + # no change of content + # replace content_xml + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'content': + bd_xml.removeChild(node) + bd_xml.appendChild(selected_content) + break + else: + # content changed + # place it under + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == 'content': + for node2 in node.childNodes: + if node2.nodeType == xml.dom.Node.ELEMENT_NODE: + if node2.nodeName == 'new_content': + node2.appendChild(selected_content) + break + #return bd_xml.toprettyxml() + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'create_bd') + f_call.appendChild(Variable('bd', bd_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + elif object_type == 'mapper': + mapper_data = get_mapper_data(self, storage_report, mapper_id) + mapper_xml = mapper_data['xml']#.cloneNode(True) + #return mapper_xml.toprettyxml() + + if action_type == 'Remove': + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'remove_mapper') + f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + elif action_type == 'Apply': + # props + props_xml = None + for node in mapper_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + if var_name in request: + if mapper_data['props'][var_name]['type'] == 'int': + if mapper_data['props'][var_name]['units'] != 'bytes': + val = int(request[var_name]) + step = int(mapper_data['props'][var_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + mapper_data['props'][var_name]['value']) + min_val = int(mapper_data['props'][var_name]['validation']['min']) + max_val = int(mapper_data['props'][var_name]['validation']['max']) + step = int(mapper_data['props'][var_name]['validation']['step']) + val_units = float(request[var_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[var_name]) + #return mapper_xml.toprettyxml() + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'modify_mapper') + f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + + elif object_type == 'mapper_template': + mapper_data = get_mapper_template_data(self, storage_report, mapper_type) + mapper_xml = mapper_data['xml']#.cloneNode(True) + #return mapper_xml.toprettyxml() + + if action_type == 'Apply': + # props + props_xml = None + for node in mapper_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + if node.getAttribute('mutable') == 'true': + var_name = node.getAttribute('name') + if request.has_key(var_name): + if mapper_data['props'][var_name]['type'] == 'int': + if mapper_data['props'][var_name]['units'] != 'bytes': + val = int(request[var_name]) + step = int(mapper_data['props'][var_name]['validation']['step']) + val = (val / step) * step + else: + dummy, units = bytes_to_value_prefunits(self, + mapper_data['props'][var_name]['value']) + min_val = int(mapper_data['props'][var_name]['validation']['min']) + max_val = int(mapper_data['props'][var_name]['validation']['max']) + step = int(mapper_data['props'][var_name]['validation']['step']) + val_units = float(request[var_name]) + val = int(val_units * get_units_multiplier(units)) + val = (val / step) * step + if val < min_val: + val = min_val + if val > max_val: + val = max_val + node.setAttribute('value', str(val)) + else: + node.setAttribute('value', request[var_name]) + + # find sources + for v in request.keys(): + if v.find('source_bd_') == 0: + if request[v] == 'on': + path = v[len('source_bd_'):] + for s_xml in storage_report.get_new_sources(mapper_xml): + if s_xml.getAttribute('path') == path: + for node in mapper_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_SOURCES_TAG: + node.appendChild(s_xml)#.cloneNode(True)) + #return mapper_xml.toprettyxml() + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "10") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'create_mapper') +# f_call.appendChild(Variable('mapper', mapper_xml.cloneNode(True)).export_xml(doc)) + f_call.appendChild(Variable('mapper', mapper_xml).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + + + elif object_type == 'add_sources': + mapper_data = get_mapper_data(self, storage_report, mapper_id) + mapper_xml = mapper_data['xml']#.cloneNode(True) + new_sources = [] + #return mapper_xml.toprettyxml() + + if action_type == 'Apply': + # find sources + for v in request.keys(): + if v.find('source_bd_') == 0: + if request[v] == 'on': + path = v[len('source_bd_'):] + for ns in mapper_data['new_sources']: + if ns['path'] == path: + new_sources.append(ns['xml'])#.cloneNode(True)) + #return mapper_xml.toprettyxml() + doc = minidom.Document() + batch = doc.createElement("batch") + module = doc.createElement("module") + module.setAttribute("name", "storage") + req = doc.createElement("request") + req.setAttribute("API_version", "1.0") + req.setAttribute("sequence", "11") + f_call = doc.createElement("function_call") + f_call.setAttribute('name', 'add_mapper_sources') + f_call.appendChild(Variable('mapper_type', mapper_type).export_xml(doc)) + f_call.appendChild(Variable('mapper_id', mapper_id).export_xml(doc)) + f_call.appendChild(Variable('mapper_state_ind', mapper_xml.getAttribute('state_ind')).export_xml(doc)) + f_call.appendChild(VariableList('bds', new_sources, [], VARIABLE_TYPE_LIST_XML).export_xml(doc)) + + req.appendChild(f_call) + module.appendChild(req) + batch.appendChild(module) + + res = ricci.process_batch(batch, True) + batch_id = res.getAttribute('batch_id') + + + if batch_id == '': + raise Exception, '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 is None: + # ricci down + error = True + url = url + msg = 'Unable to contact %s' % 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 %s responded with error. No detailed info available.' % storagename + elif batch is None: + # no such batch + error = False + completed = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'No such batch' + else: + 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 = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Ricci on %s sent a malformed response' % storagename + 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 = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Ricci on %s removed request from scheduler. File bug report against ricci.' % storagename + elif code == -104: + # module failure + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Ricci on %s failed to execute storage module; reinstall it.' % storagename + elif code == -2: + # API error + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Luci server used invalid API to communicate with %s. File a bug report against luci.' % storagename + elif code == -1: + # undefined error + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Reason for failure (as reported by %s): %s' % (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 = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Mid-Air collision (storage on %s has changed since last probe).' % storagename + elif code == 2: + # validation error + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Validation error. File bug report against Luci.' + elif code == 3: + # unmount error + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Unmount failure: %s' % err_msg + elif code == 4: + # clvmd error + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'clvmd (clustered LVM daemon) is not running on %s' % storagename + elif code == 5: + # not quorate + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Cluster quorum is required, but cluster is not quorate. Start cluster, and try again.' + elif code == 6: + # LVM cluster locking not enabled + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'LVM cluster locking is not enabled on %s' % storagename + elif code == 7: + # cluster not running + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = 'Cluster infrastructure is not running on %s' % storagename + elif code > 8: + error = True + url = '%s?%s=%s&%s=%s' \ + % (index_html_URL, STONAME, storagename, PAGETYPE, STORAGE) + msg = err_msg + + return { + 'error': error, + 'completed': completed, + 'redirect_url': url, + 'msg': msg + } ######### internal functions (not to be exposed) ############## +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 is None: + raise Exception, '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 is None: + raise Exception, '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 is None: + raise Exception, 'missing in ' + rvars = {} + for node in fr_r.childNodes: + try: + var = parse_variable(node) + rvars[var.get_name()] = var + except: + pass + + mapper_id = '' + mapper_type = '' + bd_path = '' + if 'mapper' in rvars: + mapper = rvars['mapper'].get_value() + mapper_type = mapper.getAttribute('mapper_type') + mapper_id = mapper.getAttribute('mapper_id') + if 'bd' in rvars: + bd = rvars['bd'].get_value() + bd_path = bd.getAttribute('path') + mapper_type = bd.getAttribute('mapper_type') + mapper_id = bd.getAttribute('mapper_id') + + url_list = list() + url_list.append('%s?%s=%s' % (main_url, STONAME, storagename)) + if mapper_type != '': + url_list.append('&%s=%s' % (PT_MAPPER_TYPE, mapper_type)) + if mapper_id != '': + url_list.append('&%s=%s' % (PT_MAPPER_ID, mapper_id)) + if bd_path != '': + url_list.append('&%s=%s' % (PT_PATH, bd_path)) + + if mapper_type == '': + url_list.append('&%s=%s' % (PAGETYPE, STORAGE)) + elif bd_path != '': + url_list.append('&%s=%s' % (PAGETYPE, VIEW_BD)) + else: + url_list.append('&%s=%s' % (PAGETYPE, VIEW_MAPPER)) - -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 is None: - raise Exception, '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 is None: - raise Exception, '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 is None: - raise Exception, 'missing in ' - rvars = {} - for node in fr_r.childNodes: - try: - var = parse_variable(node) - rvars[var.get_name()] = var - except: - pass - - - mapper_id = '' - mapper_type = '' - bd_path = '' - if 'mapper' in rvars: - mapper = rvars['mapper'].get_value() - mapper_type = mapper.getAttribute('mapper_type') - mapper_id = mapper.getAttribute('mapper_id') - if 'bd' in rvars: - bd = rvars['bd'].get_value() - bd_path = bd.getAttribute('path') - mapper_type = bd.getAttribute('mapper_type') - mapper_id = bd.getAttribute('mapper_id') - - url_list = list() - url_list.append('%s?%s=%s' % (main_url, STONAME, storagename)) - if mapper_type != '': - url_list.append('&%s=%s' % (PT_MAPPER_TYPE, mapper_type)) - if mapper_id != '': - url_list.append('&%s=%s' % (PT_MAPPER_ID, mapper_id)) - if bd_path != '': - url_list.append('&%s=%s' % (PT_PATH, bd_path)) - - if mapper_type == '': - url_list.append('&%s=%s' % (PAGETYPE, STORAGE)) - elif bd_path != '': - url_list.append('&%s=%s' % (PAGETYPE, VIEW_BD)) - else: - url_list.append('&%s=%s' % (PAGETYPE, VIEW_MAPPER)) - - return ''.join(url_list) + return ''.join(url_list) def get_bd_data_internal(session, bd_xml, mapper_xml): - data = {} + data = {} - removable, props = get_props_data_internal(session, bd_xml) + removable, props = get_props_data_internal(session, bd_xml) - path = bd_xml.getAttribute('path') - mapper_type = bd_xml.getAttribute('mapper_type') - mapper_id = bd_xml.getAttribute('mapper_id') - contents = get_content_data_internal(session, bd_xml) - - pretty_mapper_type, pretty_type, dummy2 = get_pretty_mapper_info(mapper_type) - pretty_name = path.replace('/dev/','') - dummy1, icon_name, dummy2 = get_mapper_icons(mapper_type) - color = 'black' - - size_in_units, units = bytes_to_value_units(props['size']['value']) - - description = None - if mapper_type == MAPPER_SYS_TYPE: - if 'scsi_id' in props: - description = '%s %s, SCSI ID = %s' \ - % (size_in_units, units, props['scsi_id']['value']) - icon_name = 'icon_bd_scsi.png' - elif mapper_type == MAPPER_VG_TYPE: - pretty_name = props['lvname']['value'] - color = '#0192db' - if props['snapshot']['value'] == 'true': - icon_name = 'icon_bd_LV_snapshot.png' - pretty_type = 'Snapshot' - - if description is None: - description = '%s %s' % (size_in_units, units) - - if bd_xml.nodeName == BD_TEMPLATE: - if mapper_type == MAPPER_PT_TYPE: - path = 'unused_segment_%s_%s' \ - % (props['partition_begin']['value'], props['partition_type']['value']) - else: - path = 'unused_segment' - pretty_type = 'New %s' % pretty_type - pretty_name = 'Unused Space' - data['new'] = True - else: - data['new'] = False - if mapper_type == MAPPER_VG_TYPE: - if props['snapshot']['value'] == 'true': - if data['new']: - contents = [] - path = 'new_snapshot' - pretty_name = '' - - data['pretty_mapper_type'] = pretty_mapper_type - data['pretty_type'] = pretty_type - data['pretty_name'] = pretty_name - data['description'] = description - data['props'] = props - data['props_ordered'] = get_ordered_props(props) - data['path'] = path - data['mapper_type'] = mapper_type - data['mapper_id'] = mapper_id - data['contents'] = contents - data['icon'] = icon_name - data['color'] = color - data['xml'] = bd_xml#.cloneNode(True) - - actions = [] - if removable: - action = {'name' : 'Remove', - 'msg' : 'Are you sure you want to remove %s \\\'%s\\\'?' \ - % (pretty_type, pretty_name), - 'link' : ''} - actions.append(action) - if data['mapper_type'] == MAPPER_VG_TYPE and not data['new']: - nts = None - for node in mapper_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == MAPPER_NEW_TARGETS_TAG: - nts = node - snap_lv = None - for node in nts.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == BD_TEMPLATE: - snap_lv = get_bd_data_internal(session, node, mapper_xml) - - if snap_lv is not None and snap_lv['props']['clustered']['value'] != 'true': - if snap_lv['props']['snapshot']['value'] == 'true': - origs = snap_lv['props']['snapshot_origin']['value'] - if pretty_name in origs: - action = {'name' : 'Take Snapshot', - 'msg' : '', - 'link' : './?%s=%s&%s=%s&%s=%s&%s=%s' \ - % (PAGETYPE, VIEW_BD, \ - PT_MAPPER_ID, data['mapper_id'], \ - PT_MAPPER_TYPE, data['mapper_type'], \ - PT_PATH, snap_lv['path'])} - actions.append(action) - data['actions'] = actions - - need_apply_butt = mutable_props(data['props']) - if need_apply_butt is False: - if len(data['contents']) > 1: - need_apply_butt = True - elif len(data['contents']) == 1: - need_apply_butt = mutable_props(data['contents'][0]['props']) - else: - need_apply_butt = False - data['need_apply_button'] = need_apply_butt - - return data + path = bd_xml.getAttribute('path') + mapper_type = bd_xml.getAttribute('mapper_type') + mapper_id = bd_xml.getAttribute('mapper_id') + contents = get_content_data_internal(session, bd_xml) + + pretty_mapper_type, pretty_type, dummy2 = get_pretty_mapper_info(mapper_type) + pretty_name = path.replace('/dev/','') + dummy1, icon_name, dummy2 = get_mapper_icons(mapper_type) + color = 'black' + + size_in_units, units = bytes_to_value_units(props['size']['value']) + + description = None + if mapper_type == MAPPER_SYS_TYPE: + if 'scsi_id' in props: + description = '%s %s, SCSI ID = %s' \ + % (size_in_units, units, props['scsi_id']['value']) + icon_name = 'icon_bd_scsi.png' + elif mapper_type == MAPPER_VG_TYPE: + pretty_name = props['lvname']['value'] + color = '#0192db' + if props['snapshot']['value'] == 'true': + icon_name = 'icon_bd_LV_snapshot.png' + pretty_type = 'Snapshot' + + if description is None: + description = '%s %s' % (size_in_units, units) + + if bd_xml.nodeName == BD_TEMPLATE: + if mapper_type == MAPPER_PT_TYPE: + path = 'unused_segment_%s_%s' \ + % (props['partition_begin']['value'], props['partition_type']['value']) + else: + path = 'unused_segment' + pretty_type = 'New %s' % pretty_type + pretty_name = 'Unused Space' + data['new'] = True + else: + data['new'] = False + if mapper_type == MAPPER_VG_TYPE: + if props['snapshot']['value'] == 'true': + if data['new']: + contents = [] + path = 'new_snapshot' + pretty_name = '' + + data['pretty_mapper_type'] = pretty_mapper_type + data['pretty_type'] = pretty_type + data['pretty_name'] = pretty_name + data['description'] = description + data['props'] = props + data['props_ordered'] = get_ordered_props(props) + data['path'] = path + data['mapper_type'] = mapper_type + data['mapper_id'] = mapper_id + data['contents'] = contents + data['icon'] = icon_name + data['color'] = color + data['xml'] = bd_xml#.cloneNode(True) + + actions = [] + if removable: + action = { + 'name': 'Remove', + 'msg': 'Are you sure you want to remove %s \\\'%s\\\'?' \ + % (pretty_type, pretty_name), + 'link': '' + } + actions.append(action) + if data['mapper_type'] == MAPPER_VG_TYPE and not data['new']: + nts = None + for node in mapper_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == MAPPER_NEW_TARGETS_TAG: + nts = node + snap_lv = None + for node in nts.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == BD_TEMPLATE: + snap_lv = get_bd_data_internal(session, node, mapper_xml) + + if snap_lv is not None and snap_lv['props']['clustered']['value'] != 'true': + if snap_lv['props']['snapshot']['value'] == 'true': + origs = snap_lv['props']['snapshot_origin']['value'] + if pretty_name in origs: + action = { + 'name': 'Take Snapshot', + 'msg': '', + 'link': './?%s=%s&%s=%s&%s=%s&%s=%s' \ + % (PAGETYPE, VIEW_BD, \ + PT_MAPPER_ID, data['mapper_id'], \ + PT_MAPPER_TYPE, data['mapper_type'], \ + PT_PATH, snap_lv['path']) + } + actions.append(action) + data['actions'] = actions + + need_apply_butt = mutable_props(data['props']) + if need_apply_butt is False: + if len(data['contents']) > 1: + need_apply_butt = True + elif len(data['contents']) == 1: + need_apply_butt = mutable_props(data['contents'][0]['props']) + else: + need_apply_butt = False + data['need_apply_button'] = need_apply_butt + return data def get_props_data_internal(session, xml_tag): - data = {} - removable = False - + data = {} + removable = False - props_xml = None - for node in xml_tag.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == PROPS_TAG: - props_xml = node - var_xmls = {} - for node in props_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TAG: - var_xmls[node.getAttribute('name')] = node - removable = False - for name in var_xmls: - var = var_xmls[name] - mutable = var.getAttribute('mutable') == 'true' - var_type = var.getAttribute('type') - value = var.getAttribute('value') - - d_units = '' - if name in ['size', 'extent_size', 'block_size', 'size_free', 'partition_begin']: - d_units = 'bytes' - if 'percent' in name: - d_units = '%' - - validation_data = {} - if var_type == VARIABLE_TYPE_INT: - d_type = 'int' - d_value = value - min_val = var.getAttribute('min') - max_val = var.getAttribute('max') - step = var.getAttribute('step') - validation_data['min'] = str(min_val) - validation_data['max'] = str(max_val) - validation_data['step'] = str(step) - elif var_type == VARIABLE_TYPE_STRING: - d_type = 'text' - d_value = value - validation_data['min_length'] = var.getAttribute('min_length') - validation_data['max_length'] = var.getAttribute('max_length') - validation_data['illegal_chars'] = var.getAttribute('illegal_chars').replace('\'', '\\\'').replace('<', '<').replace('>', '>').replace('"', '\\\"').replace('&', '&') - validation_data['reserved_words'] = var.getAttribute('reserved_words') - elif var_type == VARIABLE_TYPE_INT_SEL or var_type == VARIABLE_TYPE_STRING_SEL: - d_type = 'select' - d_value = [value] - for node in var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TYPE_LISTENTRY: - val = node.getAttribute('value') - if val not in d_value: - d_value.append(val) - elif var_type == VARIABLE_TYPE_BOOL: - d_type = 'select' - d_value = [value] - if value == 'true': - d_value.append('false') - else: - d_value.append('true') - elif var_type == VARIABLE_TYPE_LIST_INT or var_type == VARIABLE_TYPE_LIST_STR: - d_type = 'label' - d_value = '' - d_val_list = list() - for node in var.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == VARIABLE_TYPE_LISTENTRY: - d_val_list.append(node.getAttribute('value')) - d_val_list.append(', ') - d_value = ''.join(d_val_list) - if d_value != '': - d_value = d_value[:len(d_value)-2] - elif var_type == 'hidden': - d_type = 'hidden' - d_value = str(value) - else: - d_type = 'label' - d_value = value - - if not mutable and d_type != 'label' and d_type != 'hidden': - d_type = 'label' - d_value = str(value) - - hidden = False - if var_type == 'hidden' or name in ['partition_begin', 'snapshot']: - hidden = True - - if name == 'removable': - removable = value == 'true' - elif name == 'path': - pass - else: - data[name] = {'name' : name, - 'pretty_name' : get_pretty_prop_name(name), - 'type' : d_type, - 'value' : d_value, - 'units' : d_units, - 'validation' : validation_data, - 'hidden' : hidden} + props_xml = None + for node in xml_tag.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == PROPS_TAG: + props_xml = node + + var_xmls = {} + for node in props_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TAG: + var_xmls[node.getAttribute('name')] = node + + removable = False + for name in var_xmls: + var = var_xmls[name] + mutable = var.getAttribute('mutable') == 'true' + var_type = var.getAttribute('type') + value = var.getAttribute('value') + + d_units = '' + if name in ['size', 'extent_size', 'block_size', 'size_free', 'partition_begin']: + d_units = 'bytes' + if 'percent' in name: + d_units = '%' + + validation_data = {} + if var_type == VARIABLE_TYPE_INT: + d_type = 'int' + d_value = value + min_val = var.getAttribute('min') + max_val = var.getAttribute('max') + step = var.getAttribute('step') + validation_data['min'] = str(min_val) + validation_data['max'] = str(max_val) + validation_data['step'] = str(step) + elif var_type == VARIABLE_TYPE_STRING: + d_type = 'text' + d_value = value + validation_data['min_length'] = var.getAttribute('min_length') + validation_data['max_length'] = var.getAttribute('max_length') + validation_data['illegal_chars'] = var.getAttribute('illegal_chars').replace('\'', '\\\'').replace('<', '<').replace('>', '>').replace('"', '\\\"').replace('&', '&') + validation_data['reserved_words'] = var.getAttribute('reserved_words') + elif var_type == VARIABLE_TYPE_INT_SEL or var_type == VARIABLE_TYPE_STRING_SEL: + d_type = 'select' + d_value = [value] + for node in var.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TYPE_LISTENTRY: + val = node.getAttribute('value') + if val not in d_value: + d_value.append(val) + elif var_type == VARIABLE_TYPE_BOOL: + d_type = 'select' + d_value = [value] + if value == 'true': + d_value.append('false') + else: + d_value.append('true') + elif var_type == VARIABLE_TYPE_LIST_INT or var_type == VARIABLE_TYPE_LIST_STR: + d_type = 'label' + d_value = '' + d_val_list = list() + for node in var.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == VARIABLE_TYPE_LISTENTRY: + d_val_list.append(node.getAttribute('value')) + d_val_list.append(', ') + d_value = ''.join(d_val_list) + if d_value != '': + d_value = d_value[:len(d_value)-2] + elif var_type == 'hidden': + d_type = 'hidden' + d_value = str(value) + else: + d_type = 'label' + d_value = value + + if not mutable and d_type != 'label' and d_type != 'hidden': + d_type = 'label' + d_value = str(value) + + hidden = False + if var_type == 'hidden' or name in ['partition_begin', 'snapshot']: + hidden = True + + if name == 'removable': + removable = value == 'true' + elif name == 'path': + pass + else: + data[name] = { + 'name': name, + 'pretty_name': get_pretty_prop_name(name), + 'type': d_type, + 'value': d_value, + 'units': d_units, + 'validation': validation_data, + 'hidden': hidden + } - return (removable, data) + return (removable, data) def get_ordered_props(props): - names = [] - sizes = [] - mounts = [] - min_max = [] - uuids = [] - rest = [] - for prop_name in props: - prop = props[prop_name] - # names - if 'name' in prop_name or 'label' in prop_name or 'vendor' == prop_name or 'model' == prop_name: - names.append(prop) - # sizes - elif 'size' in prop_name or 'extents' in prop_name or 'percent' in prop_name: - sizes.append(prop) - # mounts - elif 'mount' in prop_name or 'fstab' in prop_name: - mounts.append(prop) - # min_max - elif 'min' in prop_name or 'max' in prop_name: - min_max.append(prop) - elif 'uuid' in prop_name: - uuids.append(prop) - else: - rest.append(prop) - - ordered = [] - for prop in names: - ordered.append(prop) - for prop in sizes: - ordered.append(prop) - for prop in mounts: - ordered.append(prop) - for prop in min_max: - ordered.append(prop) - for prop in rest: - ordered.append(prop) - for prop in uuids: - ordered.append(prop) - return ordered + names = [] + sizes = [] + mounts = [] + min_max = [] + uuids = [] + rest = [] + + for prop_name in props: + prop = props[prop_name] + # names + if 'name' in prop_name or 'label' in prop_name or 'vendor' == prop_name or 'model' == prop_name: + names.append(prop) + # sizes + elif 'size' in prop_name or 'extents' in prop_name or 'percent' in prop_name: + sizes.append(prop) + # mounts + elif 'mount' in prop_name or 'fstab' in prop_name: + mounts.append(prop) + # min_max + elif 'min' in prop_name or 'max' in prop_name: + min_max.append(prop) + elif 'uuid' in prop_name: + uuids.append(prop) + else: + rest.append(prop) + + ordered = [] + for prop in names: + ordered.append(prop) + for prop in sizes: + ordered.append(prop) + for prop in mounts: + ordered.append(prop) + for prop in min_max: + ordered.append(prop) + for prop in rest: + ordered.append(prop) + for prop in uuids: + ordered.append(prop) + return ordered def mutable_props(props): - for name in props: - prop_type = props[name]['type'] - if prop_type == 'int' or prop_type == 'text' or prop_type == 'select': - return True - return False + for name in props: + prop_type = props[name]['type'] + if prop_type == 'int' or prop_type == 'text' or prop_type == 'select': + return True + return False def get_content_data_internal(session, bd_xml): - c_xml = None - for node in bd_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == CONTENT_TYPE: - c_xml = node - break - if c_xml is None: - return {} - - a_xmls = [] - for node in c_xml.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == "available_contents": - a_conts = node - for node in a_conts.childNodes: - if node.nodeType == xml.dom.Node.ELEMENT_NODE: - if node.nodeName == "content_template": - a_xmls.append(node) - break - - current = {} - removable, props = get_props_data_internal(session, c_xml) - current['props'] = props - name, content_id = get_content_name_id(c_xml) - current['name'] = name - current['id'] = content_id - current['xml'] = c_xml#.cloneNode(True) - - data = [current] - for a_xml in a_xmls: - available = {} - removable, props = get_props_data_internal(session, a_xml) - available['props'] = props - name, content_id = get_content_name_id(a_xml) - available['name'] = name - available['id'] = content_id - available['xml'] = a_xml#.cloneNode(True) - - data.append(available) - - for d in data: - old_props = d['props'] - new_props = {} - for name in old_props: - new_name = 'content_variable_%s_%s' % (d['id'], name) - new_props[new_name] = old_props[name] - new_props[new_name]['name'] = new_name - d['props'] = new_props - d['props_ordered'] = get_ordered_props(new_props) - d['is_source'] = False - - # content's color and icon - color = 'black' - icon_name = '' - content_type = d['xml'].getAttribute('type') - if content_type == 'filesystem': - icon_name = get_fs_icon(d['xml'].getAttribute('fs_type')) - elif content_type == 'mapper_source': - mapper_type = d['xml'].getAttribute('mapper_type') - mapper_id = d['xml'].getAttribute('mapper_id') - pretty_mapper_type, dummy1, dummy2 = get_pretty_mapper_info(mapper_type) - dummy1, dummy2, icon_name = get_mapper_icons(mapper_type) - if mapper_type == MAPPER_VG_TYPE: - color = '#a43737' - d['is_source'] = True - d['mapper_type'] = mapper_type - d['mapper_id'] = mapper_id - d['pretty_mapper_type'] = pretty_mapper_type - elif content_type == 'none': - pass - elif content_type == 'hidden': - pass + c_xml = None + for node in bd_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == CONTENT_TYPE: + c_xml = node + break + if c_xml is None: + return {} + + a_xmls = [] + for node in c_xml.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == "available_contents": + a_conts = node + for node in a_conts.childNodes: + if node.nodeType == xml.dom.Node.ELEMENT_NODE: + if node.nodeName == "content_template": + a_xmls.append(node) + break + + current = {} + removable, props = get_props_data_internal(session, c_xml) + current['props'] = props + name, content_id = get_content_name_id(c_xml) + current['name'] = name + current['id'] = content_id + current['xml'] = c_xml#.cloneNode(True) + + data = [current] + for a_xml in a_xmls: + available = {} + removable, props = get_props_data_internal(session, a_xml) + available['props'] = props + name, content_id = get_content_name_id(a_xml) + available['name'] = name + available['id'] = content_id + available['xml'] = a_xml#.cloneNode(True) + + data.append(available) + + for d in data: + old_props = d['props'] + new_props = {} + for name in old_props: + new_name = 'content_variable_%s_%s' % (d['id'], name) + new_props[new_name] = old_props[name] + new_props[new_name]['name'] = new_name + d['props'] = new_props + d['props_ordered'] = get_ordered_props(new_props) + d['is_source'] = False + + # content's color and icon + color = 'black' + icon_name = '' + content_type = d['xml'].getAttribute('type') + if content_type == 'filesystem': + icon_name = get_fs_icon(d['xml'].getAttribute('fs_type')) + elif content_type == 'mapper_source': + mapper_type = d['xml'].getAttribute('mapper_type') + mapper_id = d['xml'].getAttribute('mapper_id') + pretty_mapper_type, dummy1, dummy2 = get_pretty_mapper_info(mapper_type) + dummy1, dummy2, icon_name = get_mapper_icons(mapper_type) + if mapper_type == MAPPER_VG_TYPE: + color = '#a43737' + d['is_source'] = True + d['mapper_type'] = mapper_type + d['mapper_id'] = mapper_id + d['pretty_mapper_type'] = pretty_mapper_type + elif content_type == 'none': + pass + elif content_type == 'hidden': + pass - d['color'] = color - d['icon'] = icon_name + d['color'] = color + d['icon'] = icon_name - return data + return data def get_content_name_id(c_xml): - name = 'Unknown type' - content_id = c_xml.getAttribute('type') - if content_id == CONTENT_FS_TYPE: - fs_type = c_xml.getAttribute('fs_type') - content_id = '%s_%s' % (content_id, fs_type) - name = get_pretty_fs_name(fs_type) - elif content_id == CONTENT_NONE_TYPE: - name = 'Empty' - elif content_id == CONTENT_MS_TYPE: - mapper_type = c_xml.getAttribute('mapper_type') - mapper_id = c_xml.getAttribute('mapper_id') - content_id = '%s_%s_%s' % (content_id, mapper_type, mapper_id.replace(':', '__colon__')) - if mapper_type == MAPPER_SYS_TYPE: - pass - elif mapper_type == MAPPER_VG_TYPE: - name = 'Physical Volume' - elif mapper_type == MAPPER_PT_TYPE: - name = 'Partition Table' - elif mapper_type == MAPPER_MDRAID_TYPE: - name = 'Software RAID Disk' - elif mapper_type == MAPPER_ATARAID_TYPE: - name = 'ATA-RAID Disk' - elif mapper_type == MAPPER_MULTIPATH_TYPE: - name = 'Multipath\'s Path' - elif mapper_type == MAPPER_CRYPTO_TYPE: - name = 'Encrypted Device' - elif mapper_type == MAPPER_iSCSI_TYPE: - pass - else: - name = 'Source of %s' % mapper_type - elif content_id == CONTENT_HIDDEN_TYPE: - name = 'Extended Partition' - else: - name = 'Unknown type' + name = 'Unknown type' + content_id = c_xml.getAttribute('type') + if content_id == CONTENT_FS_TYPE: + fs_type = c_xml.getAttribute('fs_type') + content_id = '%s_%s' % (content_id, fs_type) + name = get_pretty_fs_name(fs_type) + elif content_id == CONTENT_NONE_TYPE: + name = 'Empty' + elif content_id == CONTENT_MS_TYPE: + mapper_type = c_xml.getAttribute('mapper_type') + mapper_id = c_xml.getAttribute('mapper_id') + content_id = '%s_%s_%s' % (content_id, mapper_type, mapper_id.replace(':', '__colon__')) + if mapper_type == MAPPER_SYS_TYPE: + pass + elif mapper_type == MAPPER_VG_TYPE: + name = 'Physical Volume' + elif mapper_type == MAPPER_PT_TYPE: + name = 'Partition Table' + elif mapper_type == MAPPER_MDRAID_TYPE: + name = 'Software RAID Disk' + elif mapper_type == MAPPER_ATARAID_TYPE: + name = 'ATA-RAID Disk' + elif mapper_type == MAPPER_MULTIPATH_TYPE: + name = 'Multipath\'s Path' + elif mapper_type == MAPPER_CRYPTO_TYPE: + name = 'Encrypted Device' + elif mapper_type == MAPPER_iSCSI_TYPE: + pass + else: + name = 'Source of %s' % mapper_type + elif content_id == CONTENT_HIDDEN_TYPE: + name = 'Extended Partition' + else: + name = 'Unknown type' - return name, content_id + return name, content_id def group_systems_by_cluster(self, allowed_systems, from_cache=False): - ss = get_systems_statuses(self, allowed_systems, from_cache) - clusters = {} - bad_list = [] - for s in ss: - if s['authed']: - cluname = s['cluname'] - if cluname not in clusters: - clusters[cluname] = [] - clusters[cluname].append(s) - else: - bad_list.append(s) - clu_list = [] - nonclu_list = [] - for cluname in clusters: - if cluname == '': - nonclu_list = clusters[cluname] - else: - cl = {'name' : cluname, - 'alias' : clusters[cluname][0]['clualias'], - 'nodes' : clusters[cluname]} - clu_list.append(cl) - - ret = [nonclu_list, clu_list, bad_list] - - return ret - - - - -def get_mappings_info(self, - mapper_data, - length): - # highlights - high_list = {} - - # upper cyl - upper_cyl = {'offset' : 0, - 'cyls' : [], - 'highs' : [], - 'js' : [], - 'color' : 'blue', - 'color_css' : '#0192db', - 'description': mapper_data['pretty_targets_name']} - if mapper_data['mapper_type'] == MAPPER_PT_TYPE: - upper_cyl['description'] = 'Physical %s' % upper_cyl['description'] - - offset = 0 - for t in mapper_data['targets_all']: - if t['mapper_type'] == MAPPER_PT_TYPE: - if t['props']['partition_type']['value'] == 'logical': - continue - data = {} - data['bd'] = t - data['id'] = t['path'] - beg = offset - end = beg + int(t['props']['size']['value']) - data['beg'] = beg - data['end'] = end - data['color'] = 'blue' - data['color_css'] = '#0192db' - if mapper_data['mapper_type'] == MAPPER_PT_TYPE: - if t['props']['partition_type']['value'] == 'extended' and not t['new']: - data['color'] = 'black' - data['color_css'] = 'black' - upper_cyl['cyls'].append(data) - offset = end - - # scale ranges - for d in upper_cyl['cyls']: - d['beg'] = d['beg'] * length / offset - d['end'] = d['end'] * length / offset - 1 - - # build highlights - for d in upper_cyl['cyls']: - h_id = '%s_selected' % d['id'] - beg = d['beg'] - end = d['end'] - upper_cyl['highs'].append({'beg' : beg, - 'end' : end, - 'id' : h_id, - 'type' : 'select'}) - upper_cyl['js'].append([d['id'], - [beg, end], - d['bd']['pretty_name']]) - high_list[d['id']] = [h_id] - - # snapshots - bd = d['bd'] - if bd['mapper_type'] == MAPPER_VG_TYPE and not bd['new']: - if 'origin' in bd: - # snapshot - snap_id = '%s_snapshot' % bd['path'] - upper_cyl['highs'].append({'beg' : beg, - 'end' : end, - 'id' : snap_id, - 'type' : 'snapshot'}) - orig = bd['origin'] - high_list[d['id']].append('%s_origin' % orig['path']) - high_list[d['id']].append(snap_id) - if 'snapshots' in bd: - # origin - upper_cyl['highs'].append({'beg' : beg, - 'end' : end, - 'id' : '%s_origin' % bd['path'], - 'type' : 'snapshot-origin'}) - for snap in bd['snapshots']: - high_list[d['id']].append('%s_snapshot' % snap['path']) - - - - upper_cyl['js'] = str(upper_cyl['js']).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') - - # lower cylinder - lower_cyl = {'offset' : 0, - 'cyls' : [], - 'highs' : [], - 'js' : [], - 'color' : 'red', - 'color_css' : '#a43737', - 'description': mapper_data['pretty_sources_name']} - - offset = 0 - for t in mapper_data['sources']: - data = {} - data['bd'] = t - data['id'] = t['path'] - beg = offset - end = beg + int(t['props']['size']['value']) - data['beg'] = beg - data['end'] = end - data['color'] = 'red' - data['color_css'] = '#a43737' - lower_cyl['cyls'].append(data) - offset = end - - if mapper_data['mapper_type'] == MAPPER_PT_TYPE: - lower_cyl['description'] = 'Logical %s' % mapper_data['pretty_targets_name'] - lower_cyl['cyls'] = [] - lower_cyl['color'] = 'blue' - lower_cyl['color_css'] = '#0192db' - lower_cyl['offset'] = 9999999999999999999999999 - - offset = 0 - for t in mapper_data['targets_all']: - if t['props']['partition_type']['value'] != 'logical': - continue - part_beg = int(t['props']['partition_begin']['value']) - if part_beg < lower_cyl['offset']: - lower_cyl['offset'] = part_beg - data = {} - data['bd'] = t - data['id'] = t['path'] - beg = offset - end = beg + int(t['props']['size']['value']) - data['beg'] = beg - data['end'] = end - data['color'] = 'blue' - data['color_css'] = '#0192db' - lower_cyl['cyls'].append(data) - offset = end - - - # scale ranges - length_in_bytes = 0 - for t in mapper_data['sources']: - length_in_bytes += int(t['props']['size']['value']) - ppb = (length * 1.0) / max(0.00001, length_in_bytes) # pixels per byte - lower_cyl['offset'] = int(lower_cyl['offset'] * ppb) - for d in lower_cyl['cyls']: - d['beg'] = int(d['beg'] * ppb) - d['end'] = int(d['end'] * ppb - 1) - - - - # build highlights - for d in lower_cyl['cyls']: - h_id = '%s_selected' % d['id'] - beg = d['beg'] - end = d['end'] - lower_cyl['highs'].append({'beg' : beg, - 'end' : end, - 'id' : h_id, - 'type' : 'select'}) - lower_cyl['js'].append([d['id'], - [beg, end], - d['bd']['pretty_name']]) - high_list[d['id']] = [h_id] - lower_cyl['js'] = str(lower_cyl['js']).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') - - # transform list of highlights - high_list_js = [[mapper_data['mapper_id'], []]] - for hl_id in high_list: - high_list_js.append([hl_id, high_list[hl_id]]) - high_list_js = str(high_list_js).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') - - # put everything together - ret = {} - ret['mapper'] = mapper_data - ret['upper_cyl'] = upper_cyl - ret['lower_cyl'] = lower_cyl - ret['js'] = high_list_js - - return ret + ss = get_systems_statuses(self, allowed_systems, from_cache) + clusters = {} + bad_list = [] + for s in ss: + if s['authed']: + cluname = s['cluname'] + if cluname not in clusters: + clusters[cluname] = [] + clusters[cluname].append(s) + else: + bad_list.append(s) + clu_list = [] + nonclu_list = [] + for cluname in clusters: + if cluname == '': + nonclu_list = clusters[cluname] + else: + cl = { + 'name': cluname, + 'alias': clusters[cluname][0]['clualias'], + 'nodes': clusters[cluname] + } + clu_list.append(cl) + + ret = [ nonclu_list, clu_list, bad_list ] + return ret + +def get_mappings_info(self, mapper_data, length): + # highlights + high_list = {} + + # upper cyl + upper_cyl = { + 'offset': 0, + 'cyls': [], + 'highs': [], + 'js': [], + 'color': 'blue', + 'color_css': '#0192db', + 'description': mapper_data['pretty_targets_name'] + } + + if mapper_data['mapper_type'] == MAPPER_PT_TYPE: + upper_cyl['description'] = 'Physical %s' % upper_cyl['description'] + + offset = 0 + for t in mapper_data['targets_all']: + if t['mapper_type'] == MAPPER_PT_TYPE: + if t['props']['partition_type']['value'] == 'logical': + continue + + data = {} + data['bd'] = t + data['id'] = t['path'] + beg = offset + end = beg + int(t['props']['size']['value']) + data['beg'] = beg + data['end'] = end + data['color'] = 'blue' + data['color_css'] = '#0192db' + + if mapper_data['mapper_type'] == MAPPER_PT_TYPE: + if t['props']['partition_type']['value'] == 'extended' and not t['new']: + data['color'] = 'black' + data['color_css'] = 'black' + upper_cyl['cyls'].append(data) + offset = end + + # scale ranges + for d in upper_cyl['cyls']: + d['beg'] = d['beg'] * length / offset + d['end'] = d['end'] * length / offset - 1 + + # build highlights + for d in upper_cyl['cyls']: + h_id = '%s_selected' % d['id'] + beg = d['beg'] + end = d['end'] + upper_cyl['highs'].append({ + 'beg': beg, + 'end': end, + 'id': h_id, + 'type': 'select' + }) + + upper_cyl['js'].append([d['id'], [beg, end], d['bd']['pretty_name']]) + high_list[d['id']] = [h_id] + + # snapshots + bd = d['bd'] + if bd['mapper_type'] == MAPPER_VG_TYPE and not bd['new']: + if 'origin' in bd: + # snapshot + snap_id = '%s_snapshot' % bd['path'] + upper_cyl['highs'].append({ + 'beg': beg, + 'end': end, + 'id': snap_id, + 'type': 'snapshot' + }) + orig = bd['origin'] + high_list[d['id']].append('%s_origin' % orig['path']) + high_list[d['id']].append(snap_id) + if 'snapshots' in bd: + # origin + upper_cyl['highs'].append({ + 'beg': beg, + 'end': end, + 'id': '%s_origin' % bd['path'], + 'type': 'snapshot-origin' + }) + for snap in bd['snapshots']: + high_list[d['id']].append('%s_snapshot' % snap['path']) + + upper_cyl['js'] = str(upper_cyl['js']).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') + + # lower cylinder + lower_cyl = { + 'offset': 0, + 'cyls': [], + 'highs': [], + 'js': [], + 'color': 'red', + 'color_css': '#a43737', + 'description': mapper_data['pretty_sources_name'] + } + + offset = 0 + for t in mapper_data['sources']: + data = {} + data['bd'] = t + data['id'] = t['path'] + beg = offset + end = beg + int(t['props']['size']['value']) + data['beg'] = beg + data['end'] = end + data['color'] = 'red' + data['color_css'] = '#a43737' + lower_cyl['cyls'].append(data) + offset = end + + if mapper_data['mapper_type'] == MAPPER_PT_TYPE: + lower_cyl['description'] = 'Logical %s' % mapper_data['pretty_targets_name'] + lower_cyl['cyls'] = [] + lower_cyl['color'] = 'blue' + lower_cyl['color_css'] = '#0192db' + lower_cyl['offset'] = 9999999999999999999999999 + + offset = 0 + for t in mapper_data['targets_all']: + if t['props']['partition_type']['value'] != 'logical': + continue + part_beg = int(t['props']['partition_begin']['value']) + if part_beg < lower_cyl['offset']: + lower_cyl['offset'] = part_beg + data = {} + data['bd'] = t + data['id'] = t['path'] + beg = offset + end = beg + int(t['props']['size']['value']) + data['beg'] = beg + data['end'] = end + data['color'] = 'blue' + data['color_css'] = '#0192db' + lower_cyl['cyls'].append(data) + offset = end + + + # scale ranges + length_in_bytes = 0 + for t in mapper_data['sources']: + length_in_bytes += int(t['props']['size']['value']) + ppb = (length * 1.0) / max(0.00001, length_in_bytes) # pixels per byte + lower_cyl['offset'] = int(lower_cyl['offset'] * ppb) + for d in lower_cyl['cyls']: + d['beg'] = int(d['beg'] * ppb) + d['end'] = int(d['end'] * ppb - 1) + + + + # build highlights + for d in lower_cyl['cyls']: + h_id = '%s_selected' % d['id'] + beg = d['beg'] + end = d['end'] + lower_cyl['highs'].append({ + 'beg': beg, + 'end': end, + 'id': h_id, + 'type': 'select' + }) + lower_cyl['js'].append([d['id'], + [beg, end], + d['bd']['pretty_name']]) + high_list[d['id']] = [h_id] + lower_cyl['js'] = str(lower_cyl['js']).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') + + # transform list of highlights + high_list_js = [[mapper_data['mapper_id'], []]] + for hl_id in high_list: + high_list_js.append([hl_id, high_list[hl_id]]) + high_list_js = str(high_list_js).replace('L,', ',').replace('L]', ']').replace('u\'', '\'').replace('L]', ']') + + # put everything together + ret = {} + ret['mapper'] = mapper_data + ret['upper_cyl'] = upper_cyl + ret['lower_cyl'] = lower_cyl + ret['js'] = high_list_js + return ret --- conga/luci/site/luci/Extensions/storage_adapters.py 2007/06/27 08:14:13 1.11 +++ conga/luci/site/luci/Extensions/storage_adapters.py 2007/09/24 19:48:34 1.12 @@ -18,362 +18,291 @@ from StorageReport import invalidate_storage_report def createStorageChooser(self, request, systems): - dummynode = {} - - #First, see if a storage system is chosen, then - #check that the current user can access that system - stoname = None - try: - stoname = request[STONAME] - except KeyError, e: - stoname = "" - - try: - url = request['URL'] - except KeyError, e: - url = "." - - if stoname and request.has_key('reprobe_storage'): - try: - invalidate_storage_report(request.SESSION, stoname) - redirect_url = '%s?%s' % (request['ACTUAL_URL'], request['QUERY_STRING']) - redirect_url = redirect_url.replace('&reprobe_storage=true', '') - request.RESPONSE.redirect(redirect_url) - except: - pass - - try: - pagetype = request[PAGETYPE] - except KeyError, e: - pagetype = "0" - - sdata = {} - sdata['Title'] = "System List" - sdata['cfg_type'] = "storages" - sdata['absolute_url'] = "%s?pagetype=%s" % (url, STORAGESYS) - sdata['Description'] = "Systems available for storage configuration" - if pagetype == STORAGESYS or pagetype == '0': - sdata['currentItem'] = True - else: - sdata['currentItem'] = False - if pagetype == STORAGESYS or pagetype == '0': - sdata['show_children'] = True - else: - sdata['show_children'] = False - - - syslist = list() - if sdata['show_children']: - #display_clusters = True - display_clusters = False - if display_clusters: - sorted_data = self.group_systems_by_cluster(systems, from_cache=False) - for sdl in sorted_data[:2]: - for data in sdl: - createStorageChooser_inner(url, - pagetype, - stoname, - data, - syslist) - else: - sorted_data = get_systems_statuses(self, systems, from_cache=False) - for data in sorted_data: - createStorageChooser_inner(url, - pagetype, - stoname, - data, - syslist) - sdata['children'] = syslist - - mylist = list() - mylist.append(sdata) - #mylist.append(sadd) - #mylist.append(scfg) - dummynode['children'] = mylist - - return dummynode - - -def createStorageChooser_inner(url, - pagetype, - stoname, - system_data, - syslist): - ssys = {} - if 'nodes' in system_data: - title = system_data['name'] - if system_data['alias'] != '': - title = '%s (%s)' % (system_data['alias'], title) - ssys['Title'] = 'Cluster %s' % title - ssys['cfg_type'] = "storage" - ssys['absolute_url'] = '%s?%s=%s&%s=%s' \ - % (url, PAGETYPE, CLUSTER_STORAGE, CLUNAME, system_data['name']) - ssys['Description'] = "Configure shared storage of cluster %s" % title - ssys['currentItem'] = False - ssys['show_children'] = True - kids = [] - for node in system_data['nodes']: - createStorageChooser_inner(url, - pagetype, - stoname, - node, - kids) - ssys['children'] = kids - else: - if system_data['authed'] is False: - return - ssys['Title'] = system_data['hostname'] - ssys['cfg_type'] = "storage" - ssys['absolute_url'] = '%s?%s=%s&%s=%s' \ - % (url, PAGETYPE, STORAGE, STONAME, system_data['hostname']) - ssys['Description'] = "Configure storage on %s" % system_data['hostname'] - - if pagetype == STORAGE: - if stoname == system_data['hostname']: - ssys['currentItem'] = True - else: - ssys['currentItem'] = False - else: - ssys['currentItem'] = False - syslist.append(ssys) - return - + dummynode = {} + # First, see if a storage system is chosen, then + # check that the current user can access that system + stoname = request.get(STONAME) or '' + url = request.get('URL') or '.' + pagetype = request.get(PAGETYPE) or '0' + + try: + if stoname and request.has_key('reprobe_storage'): + invalidate_storage_report(request.SESSION, stoname) + redirect_url = '%s?%s' % (request['ACTUAL_URL'], request['QUERY_STRING']) + redirect_url = redirect_url.replace('&reprobe_storage=true', '') + request.RESPONSE.redirect(redirect_url) + except: + pass + + sdata = {} + sdata['Title'] = 'System List' + sdata['cfg_type'] = 'storages' + sdata['absolute_url'] = '%s?pagetype=%s' % (url, STORAGESYS) + sdata['Description'] = 'Systems available for storage configuration' + + if pagetype == STORAGESYS or pagetype == '0': + sdata['show_children'] = True + sdata['currentItem'] = True + else: + sdata['currentItem'] = False + sdata['show_children'] = False + + syslist = list() + if sdata['show_children']: + #display_clusters = True + display_clusters = False + if display_clusters: + sorted_data = self.group_systems_by_cluster(systems, from_cache=False) + for sdl in sorted_data[:2]: + for data in sdl: + createStorageChooser_inner(url, pagetype, stoname, data, syslist) + else: + sorted_data = get_systems_statuses(self, systems, from_cache=False) + for data in sorted_data: + createStorageChooser_inner(url, pagetype, stoname, data, syslist) + sdata['children'] = syslist + + mylist = list() + mylist.append(sdata) + #mylist.append(sadd) + #mylist.append(scfg) + dummynode['children'] = mylist + + return dummynode + +def createStorageChooser_inner(url, pagetype, stoname, system_data, syslist): + ssys = {} + if 'nodes' in system_data: + title = system_data['name'] + if system_data['alias'] != '': + title = '%s (%s)' % (system_data['alias'], title) + ssys['Title'] = 'Cluster %s' % title + ssys['cfg_type'] = 'storage' + ssys['absolute_url'] = '%s?%s=%s&%s=%s' \ + % (url, PAGETYPE, CLUSTER_STORAGE, CLUNAME, system_data['name']) + ssys['Description'] = 'Configure shared storage of cluster %s' % title + ssys['currentItem'] = False + ssys['show_children'] = True + kids = [] + for node in system_data['nodes']: + createStorageChooser_inner(url, pagetype, stoname, node, kids) + ssys['children'] = kids + else: + if system_data['authed'] is False: + return + ssys['Title'] = system_data['hostname'] + ssys['cfg_type'] = 'storage' + ssys['absolute_url'] = '%s?%s=%s&%s=%s' \ + % (url, PAGETYPE, STORAGE, STONAME, system_data['hostname']) + ssys['Description'] = 'Configure storage on %s' % system_data['hostname'] + + if pagetype == STORAGE: + if stoname == system_data['hostname']: + ssys['currentItem'] = True + else: + ssys['currentItem'] = False + else: + ssys['currentItem'] = False + syslist.append(ssys) + return def create_mapper_subitem(storage_report, request, mapper_list, mapper_templ_list): + pagetype_req = request.get(PAGETYPE) or '0' + mapper_type_req = request.get(PT_MAPPER_TYPE) or '' + mapper_id_req = request.get(PT_MAPPER_ID) or '' + path_req = request.get(PT_PATH) or '' + url = request.get('URL') or '.' + hostname = request.get(STONAME) or '' + + mapper_type = None + if len(mapper_list) != 0: + mapper_type = mapper_list[0].getAttribute('mapper_type') + if len(mapper_templ_list) != 0: + mapper_type = mapper_templ_list[0].getAttribute('mapper_type') + if mapper_type is None: + return None + + buff, dummy1, dummy2 = get_pretty_mapper_info(mapper_type) + pretty_names = '%ss' % buff + pretty_names_desc = 'Manage %ss' % buff + pretty_name_desc = 'Manage %s' % buff + pretty_new_name = 'New %s' % buff + pretty_new_name_desc = 'Create New %s' % buff + + srs_p = {} + srs_p['Title'] = pretty_names + srs_p['cfg_type'] = 'nodes' + srs_p['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, VIEW_MAPPERS, STONAME, hostname, PT_MAPPER_TYPE, mapper_type) + srs_p['Description'] = pretty_names_desc + if pagetype_req in [ VIEW_MAPPERS, VIEW_MAPPER, ADD_SOURCES, CREATE_MAPPER, VIEW_BD ] and mapper_type_req == mapper_type: + srs_p['show_children'] = True + else: + srs_p['show_children'] = False + + if pagetype_req == VIEW_MAPPERS and mapper_type_req == mapper_type: + srs_p['currentItem'] = True + else: + srs_p['currentItem'] = False + + srs_list = [] + + # new mapper + if len(mapper_templ_list) != 0: + sr = {} + sr['Title'] = pretty_new_name + sr['cfg_type'] = 'nodes' + sr['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, CREATE_MAPPER, STONAME, hostname, PT_MAPPER_TYPE, mapper_type) + sr['Description'] = pretty_new_name_desc + sr['show_children'] = False + + if pagetype_req == CREATE_MAPPER and mapper_type_req == mapper_type: + sr['currentItem'] = True + else: + sr['currentItem'] = False + + srs_list.append(sr) + + # existing mappers + for sr_xml in mapper_list: + sr_id = sr_xml.getAttribute('mapper_id') + srname = sr_id.replace('%s:' % mapper_type, '').replace('/dev/', '') + + if srname == '' and mapper_type == MAPPER_VG_TYPE and sr_id == VG_PREFIX: + #srname = 'Uninitialized PVs' + continue + + sr = {} + sr['Title'] = srname + sr['cfg_type'] = 'nodes' + sr['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, VIEW_MAPPER, STONAME, hostname, PT_MAPPER_TYPE, mapper_type, PT_MAPPER_ID, sr_id) + sr['Description'] = pretty_name_desc + + if pagetype_req in [ VIEW_MAPPER, ADD_SOURCES, VIEW_BD ] and mapper_id_req == sr_id: + sr['currentItem'] = True + else: + sr['currentItem'] = False + sr['show_children'] = False + + # targets + tgts_list = [] + for tgt_xml in storage_report.get_targets(sr_xml): + tg_path = tgt_xml.getAttribute('path') + tgname = tg_path + #if tg_path != path_req: + # continue + tg = {} + tg['Title'] = tgname + tg['cfg_type'] = 'nodes' + tg['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, VIEW_BD, STONAME, hostname, PT_MAPPER_TYPE, mapper_type, PT_MAPPER_ID, sr_id, PT_PATH, tg_path) + tg['Description'] = tgname + tg['show_children'] = False + + if pagetype_req == VIEW_BD and path_req == tg_path: + tg['currentItem'] = True + else: + tg['currentItem'] = False + tgts_list.append(tg) + + sr['children'] = tgts_list + srs_list.append(sr) + + if len(srs_list) != 0: + srs_p['children'] = srs_list + return srs_p - try: - pagetype_req = request[PAGETYPE] - except KeyError, e: - pagetype_req = '0' - try: - mapper_type_req = request[PT_MAPPER_TYPE] - except KeyError, e: - mapper_type_req = '' - try: - mapper_id_req = request[PT_MAPPER_ID] - except KeyError, e: - mapper_id_req = '' - try: - path_req = request[PT_PATH] - except KeyError, e: - path_req = '' - try: - url = request['URL'] - except KeyError, e: - url = "." - hostname = request[STONAME] - - - mapper_type = None - if len(mapper_list) != 0: - mapper_type = mapper_list[0].getAttribute('mapper_type') - if len(mapper_templ_list) != 0: - mapper_type = mapper_templ_list[0].getAttribute('mapper_type') - if mapper_type is None: - return None - - - buff, dummy1, dummy2 = get_pretty_mapper_info(mapper_type) - pretty_names = '%ss' % buff - pretty_names_desc = 'Manage %ss' % buff - pretty_name_desc = 'Manage %s' % buff - pretty_new_name = 'New %s' % buff - pretty_new_name_desc = 'Create New %s' % buff - - - srs_p = {} - srs_p['Title'] = pretty_names - srs_p['cfg_type'] = "nodes" - srs_p['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, VIEW_MAPPERS, STONAME, hostname, PT_MAPPER_TYPE, mapper_type) - srs_p['Description'] = pretty_names_desc - if (pagetype_req == VIEW_MAPPERS or pagetype_req == VIEW_MAPPER or pagetype_req == ADD_SOURCES or pagetype_req == CREATE_MAPPER or pagetype_req == VIEW_BD) and mapper_type_req == mapper_type: - srs_p['show_children'] = True - else: - srs_p['show_children'] = False - if pagetype_req == VIEW_MAPPERS and mapper_type_req == mapper_type: - srs_p['currentItem'] = True - else: - srs_p['currentItem'] = False - - srs_list = [] - - # new mapper - if len(mapper_templ_list) != 0: - sr = {} - sr['Title'] = pretty_new_name - sr['cfg_type'] = "nodes" - sr['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, CREATE_MAPPER, STONAME, hostname, PT_MAPPER_TYPE, mapper_type) - sr['Description'] = pretty_new_name_desc - sr['show_children'] = False - - if pagetype_req == CREATE_MAPPER and mapper_type_req == mapper_type: - sr['currentItem'] = True - else: - sr['currentItem'] = False - - srs_list.append(sr) - - # existing mappers - for sr_xml in mapper_list: - sr_id = sr_xml.getAttribute('mapper_id') - srname = sr_id.replace('%s:' % mapper_type, '').replace('/dev/', '') - - if srname == '' and mapper_type == MAPPER_VG_TYPE and sr_id == VG_PREFIX: - #srname = 'Uninitialized PVs' - continue - - sr = {} - sr['Title'] = srname - sr['cfg_type'] = "nodes" - sr['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, VIEW_MAPPER, STONAME, hostname, PT_MAPPER_TYPE, mapper_type, PT_MAPPER_ID, sr_id) - sr['Description'] = pretty_name_desc - - if (pagetype_req == VIEW_MAPPER or pagetype_req == ADD_SOURCES or pagetype_req == VIEW_BD) and mapper_id_req == sr_id: - sr['currentItem'] = True - else: - sr['currentItem'] = False - sr['show_children'] = False - - # targets - tgts_list = [] - for tgt_xml in storage_report.get_targets(sr_xml): - tg_path = tgt_xml.getAttribute('path') - tgname = tg_path - #if tg_path != path_req: - # continue - tg = {} - tg['Title'] = tgname - tg['cfg_type'] = "nodes" - tg['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, VIEW_BD, STONAME, hostname, PT_MAPPER_TYPE, mapper_type, PT_MAPPER_ID, sr_id, PT_PATH, tg_path) - tg['Description'] = tgname - tg['show_children'] = False - - if pagetype_req == VIEW_BD and path_req == tg_path: - tg['currentItem'] = True - else: - tg['currentItem'] = False - tgts_list.append(tg) - - sr['children'] = tgts_list - srs_list.append(sr) - - if len(srs_list) != 0: - srs_p['children'] = srs_list - return srs_p - return None - - - + return None def createStorageConfigTree(self, request, storage_report): - dummynode = {} - if storage_report is None: - return dummynode - - try: - pagetype = request[PAGETYPE] - except KeyError, e: - pagetype = '0' - try: - mapper_type = request[PT_MAPPER_TYPE] - except KeyError, e: - mapper_type = '' - try: - mapper_id = request[PT_MAPPER_ID] - except KeyError, e: - mapper_id = '' - try: - path = request[PT_PATH] - except KeyError, e: - path = '' - try: - url = request['URL'] - except KeyError, e: - url = "." - hostname = request[STONAME] - - - ### Hard Drives ### - - hds_pretty_name, hd_pretty_name, dummy = get_pretty_mapper_info(MAPPER_SYS_TYPE) - - hds_p = {} - hds_p['Title'] = hds_pretty_name - hds_p['cfg_type'] = "nodes" - hds_p['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, VIEW_BDS, STONAME, hostname, PT_MAPPER_TYPE, MAPPER_SYS_TYPE, PT_MAPPER_ID, SYSTEM_PREFIX) - hds_p['Description'] = "Manage %s" % hds_pretty_name - if (pagetype == VIEW_BDS or pagetype == VIEW_BD) and mapper_type == MAPPER_SYS_TYPE: - hds_p['show_children'] = True - else: - hds_p['show_children'] = False - if pagetype == VIEW_BDS and mapper_type == MAPPER_SYS_TYPE: - hds_p['currentItem'] = True - else: - hds_p['currentItem'] = False - - targets_list = storage_report.get_targets(storage_report.get_mapper(SYSTEM_PREFIX)) - - hds_list = [] - for target in targets_list: - sys_id = target.getAttribute('mapper_id') - hd_path = target.getAttribute('path') - - hd = {} - hd['Title'] = hd_path.replace('/dev/', '') - hd['cfg_type'] = "nodes" - hd['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s' \ - % (url, PAGETYPE, VIEW_BD, STONAME, hostname, PT_MAPPER_TYPE, MAPPER_SYS_TYPE, PT_MAPPER_ID, sys_id, PT_PATH, hd_path) - hd['Description'] = 'Manage %s' % hd_pretty_name - hd['show_children'] = False - - if pagetype == VIEW_BD and mapper_id == sys_id and path == hd_path: - hd['currentItem'] = True - else: - hd['currentItem'] = False - - hds_list.append(hd) - - hds_p['children'] = hds_list - - - - ## mappers ## - - main_kids = [hds_p] - - mappers_dir = storage_report.get_mappers_dir() - mapper_templs_dir = storage_report.get_mapper_temps_dir() - glo_dir = {} - for cur_type in mappers_dir: - glo_dir[cur_type] = [mappers_dir[cur_type], []] - for cur_type in mapper_templs_dir: - if cur_type not in glo_dir: - glo_dir[cur_type] = [[], mapper_templs_dir[cur_type]] - else: - glo_dir[cur_type][1] = mapper_templs_dir[cur_type] - - for cur_type in glo_dir: - if cur_type == MAPPER_SYS_TYPE: - continue - item = create_mapper_subitem(storage_report, request, glo_dir[cur_type][0], glo_dir[cur_type][1]) - if item is None: - continue - else: - main_kids.append(item) - dummynode['children'] = main_kids - return dummynode + dummynode = {} + if storage_report is None: + return dummynode + + pagetype = request.get(PAGETYPE) or '0' + mapper_type = request.get(PT_MAPPER_TYPE) or '' + mapper_id = request.get(PT_MAPPER_ID) or '' + path = request.get(PT_PATH) or '' + url = request.get('URL') or '.' + hostname = request.get(STONAME) or '' + + ### Hard Drives ### + + hds_pretty_name, hd_pretty_name, dummy = get_pretty_mapper_info(MAPPER_SYS_TYPE) + + hds_p = {} + hds_p['Title'] = hds_pretty_name + hds_p['cfg_type'] = 'nodes' + hds_p['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, VIEW_BDS, STONAME, hostname, PT_MAPPER_TYPE, MAPPER_SYS_TYPE, PT_MAPPER_ID, SYSTEM_PREFIX) + hds_p['Description'] = 'Manage %s' % hds_pretty_name + + if (pagetype == VIEW_BDS or pagetype == VIEW_BD) and mapper_type == MAPPER_SYS_TYPE: + hds_p['show_children'] = True + if pagetype == VIEW_BDS: + hds_p['currentItem'] = True + else: + hds_p['currentItem'] = False + else: + hds_p['show_children'] = False + + targets_list = storage_report.get_targets(storage_report.get_mapper(SYSTEM_PREFIX)) + + hds_list = [] + for target in targets_list: + sys_id = target.getAttribute('mapper_id') + hd_path = target.getAttribute('path') + + hd = {} + hd['Title'] = hd_path.replace('/dev/', '') + hd['cfg_type'] = 'nodes' + hd['absolute_url'] = '%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s' \ + % (url, PAGETYPE, VIEW_BD, STONAME, hostname, PT_MAPPER_TYPE, MAPPER_SYS_TYPE, PT_MAPPER_ID, sys_id, PT_PATH, hd_path) + hd['Description'] = 'Manage %s' % hd_pretty_name + hd['show_children'] = False + + if pagetype == VIEW_BD and mapper_id == sys_id and path == hd_path: + hd['currentItem'] = True + else: + hd['currentItem'] = False + + hds_list.append(hd) + + hds_p['children'] = hds_list + + ## mappers ## + + main_kids = [ hds_p ] + + mappers_dir = storage_report.get_mappers_dir() + mapper_templs_dir = storage_report.get_mapper_temps_dir() + + glo_dir = {} + for cur_type in mappers_dir: + glo_dir[cur_type] = [ mappers_dir[cur_type], [] ] + + for cur_type in mapper_templs_dir: + if cur_type not in glo_dir: + glo_dir[cur_type] = [ [], mapper_templs_dir[cur_type] ] + else: + glo_dir[cur_type][1] = mapper_templs_dir[cur_type] + + for cur_type in glo_dir: + if cur_type == MAPPER_SYS_TYPE: + continue + item = create_mapper_subitem(storage_report, request, glo_dir[cur_type][0], glo_dir[cur_type][1]) + if item is None: + continue + else: + main_kids.append(item) + dummynode['children'] = main_kids + return dummynode def getStorageURL(self, request, hostname): - # return URL to manage this storage system - try: - baseurl = request['URL'] - except KeyError, e: - baseurl = "." - return '%s?%s=%s&%s=%s' % (baseurl, PAGETYPE, str(STORAGE), STONAME, hostname) + # return URL to manage this storage system + baseurl = request.get('URL') or '.' + return '%s?%s=%s&%s=%s' % (baseurl, PAGETYPE, str(STORAGE), STONAME, hostname)