# Copyright (C) 2019 Intel Corporation. # SPDX-License-Identifier: BSD-3-Clause """View pages for config app. """ import os from datetime import datetime from shutil import copyfile # flask: Copyright 2010 Pallets # SPDX-License-Identifier: BSD-3-Clause # Refer to https://github.com/pallets/flask/blob/master/LICENSE.rst for the permission notice. from flask import request, render_template, Blueprint, redirect, url_for, current_app # werkzeug: Copyright 2007 Pallets # SPDX-License-Identifier: BSD-3-Clause # Refer to https://github.com/pallets/werkzeug/blob/master/LICENSE.rst for the permission notice. from werkzeug.utils import secure_filename from controller import XmlConfig from scenario_config.scenario_cfg_gen import get_scenario_item_values from scenario_config.scenario_cfg_gen import validate_scenario_setting from launch_config.launch_cfg_gen import get_launch_item_values from launch_config.launch_cfg_gen import validate_launch_setting CONFIG_APP = Blueprint('CONFIG_APP', __name__, template_folder='templates') @CONFIG_APP.route('/') def index(): """ render the index page :return: the render template of index page """ return redirect(url_for('CONFIG_APP.scenarios')) @CONFIG_APP.route('/scenario', methods=['GET']) def scenarios(): """ render the scenario parent setting page :return: the render template of scenario setting parent page """ board_info, board_type, scenario_config, launch_config = get_xml_configs() print(board_info, scenario_config, launch_config) return render_template('scenario.html', board_info_list=get_board_list(), board_info=board_info, board_type=board_type, scenarios=scenario_config.list_all(xml_type='scenario'), launches=launch_config.list_all(xml_type='uos_launcher'), scenario='', root=None) @CONFIG_APP.route('/scenario/', methods=['GET']) def scenario(scenario_name): """ render the specified scenario setting page :param scenario_name: the scenario type :return: the render template of the specified scenario setting page """ board_info, board_type, scenario_config, launch_config = \ get_xml_configs(scenario_name.startswith('user_defined_')) print(board_info, scenario_config, launch_config) current_app.config.update(SCENARIO=scenario_name) if scenario_name.startswith('user_defined_'): scenario_config.set_curr(scenario_name[13:]) else: scenario_config.set_curr(scenario_name) scenario_item_values = {} if board_info is not None and board_type is not None: scenario_file_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, scenario_name + '.xml') if scenario_name.startswith('user_defined_'): scenario_file_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', scenario_name[13:] + '.xml') if os.path.isfile(scenario_file_path): scenario_item_values = get_scenario_item_values( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', board_info+'.xml'), scenario_file_path) print('scenario_item_values: ', scenario_item_values) return render_template('scenario.html', board_info_list=get_board_list(), board_info=board_info, board_type=board_type, scenarios=scenario_config.list_all(xml_type='scenario'), launches=launch_config.list_all(xml_type='uos_launcher'), scenario=scenario_name, root=scenario_config.get_curr_root(), scenario_item_values=scenario_item_values) @CONFIG_APP.route('/launch', methods=['GET']) def launches(): """ render the parent launch setting page :return: the render template of launch setting page """ board_info, board_type, scenario_config, launch_config = get_xml_configs() print(board_info, scenario_config, launch_config) return render_template('launch.html', board_info_list=get_board_list(), board_info=board_info, board_type=board_type, scenarios=scenario_config.list_all(xml_type='scenario'), launches=launch_config.list_all(xml_type='uos_launcher'), launch='', root=None) @CONFIG_APP.route('/launch/', methods=['GET']) def launch(launch_name): """ render the specified launch setting page :param launch_name: the launch type :return: the render template of specified launch setting page """ print('launch: ', launch_name) board_info, board_type, scenario_config, launch_config = \ get_xml_configs(launch_name.startswith('user_defined_')) print(board_info, scenario_config, launch_config) if launch_name.startswith('user_defined_'): launch_config.set_curr(launch_name[13:]) else: launch_config.set_curr(launch_name) launch_item_values = {} if board_info is not None: launch_item_values = get_launch_item_values( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', board_info + '.xml')) print('launch_item_values: ', launch_item_values) return render_template('launch.html', board_info_list=get_board_list(), board_info=board_info, board_type=board_type, scenarios=scenario_config.list_all(xml_type='scenario'), launches=launch_config.list_all(xml_type='uos_launcher'), launch=launch_name, root=launch_config.get_curr_root(), scenario=current_app.config.get('SCENARIO'), launch_item_values=launch_item_values) @CONFIG_APP.route('/save_scenario', methods=['POST']) def save_scenario(): """ save scenario setting. :return: the error list for the edited scenario setting. """ scenario_config_data = request.json if request.method == "POST" else request.args print("save_scenario") print(scenario_config_data) xml_configs = \ get_xml_configs(scenario_config_data['old_scenario_name'].startswith('user_defined_')) board_type = xml_configs[1] scenario_config = xml_configs[3] if board_type is None or xml_configs[0] is None: return {'status': 'fail', 'error_list': {'error': 'Please select the board info before this operation.'}} scenario_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type) old_scenario_name = scenario_config_data['old_scenario_name'] if scenario_config_data['old_scenario_name'].startswith('user_defined_'): old_scenario_name = scenario_config_data['old_scenario_name'][13:] scenario_config.set_curr(old_scenario_name) for key in scenario_config_data: if key not in ['old_scenario_name', 'new_scenario_name', 'board_info_file', 'board_info_upload', 'generator']: if isinstance(scenario_config_data[key], list): scenario_config.set_curr_list(scenario_config_data[key], *tuple(key.split(','))) else: scenario_config.set_curr_value(scenario_config_data[key], *tuple(key.split(','))) if scenario_config_data['generator'] == 'remove_vm_kata': scenario_config.delete_curr_key('vm:desc=specific for Kata') elif scenario_config_data['generator'] == 'add_vm_kata': # clone vm kata from generic config generic_scenario_config = get_generic_scenario_config(scenario_config) generic_scenario_config_root = generic_scenario_config.get_curr_root() elem_kata = None for vm in generic_scenario_config_root.getchildren(): if 'desc' in vm.attrib and vm.attrib['desc'] == 'specific for Kata': elem_kata = vm break if elem_kata is not None: scenario_config.clone_curr_elem(elem_kata) tmp_scenario_file = os.path.join(scenario_path, 'user_defined', 'tmp_'+scenario_config_data['new_scenario_name']+'.xml') # if os.path.isfile(tmp_scenario_file): # os.remove(tmp_scenario_file) scenario_config.save('tmp_'+scenario_config_data['new_scenario_name']) # call validate function error_list = {} new_scenario_name = scenario_config_data['new_scenario_name'] rename = False try: (error_list, vm_info) = validate_scenario_setting( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', xml_configs[0]+'.xml'), tmp_scenario_file) print('vm_info: ', vm_info) except Exception as error: if os.path.isfile(tmp_scenario_file): os.remove(tmp_scenario_file) return {'status': 'fail', 'file_name': new_scenario_name, 'rename': rename, 'error_list': {'error': str(error)}} print('error_list: ', error_list) if not error_list: old_scenario_path = os.path.join(scenario_path, old_scenario_name + '.xml') if scenario_config_data['old_scenario_name'].startswith('user_defined_'): old_scenario_path = os.path.join(scenario_path, 'user_defined', old_scenario_name + '.xml') # check name conflict new_scenario_path = os.path.join(scenario_path, 'user_defined', scenario_config_data['new_scenario_name']+'.xml') if old_scenario_path != new_scenario_path and os.path.isfile(new_scenario_path): new_scenario_name = new_scenario_name + '_' + datetime.now().strftime('%Y%m%d%H%M%S') rename = True if os.path.isfile(old_scenario_path) \ and scenario_config_data['old_scenario_name'].startswith('user_defined_'): os.remove(old_scenario_path) scenario_config.save(new_scenario_name) if os.path.isfile(tmp_scenario_file): os.remove(tmp_scenario_file) return {'status': 'success', 'file_name': new_scenario_name, 'rename': rename, 'error_list': error_list} @CONFIG_APP.route('/save_launch', methods=['POST']) def save_launch(): """ save launch setting. :return: the error list of the edited launch setting. """ launch_config_data = request.json if request.method == "POST" else request.args xml_configs = \ get_xml_configs(launch_config_data['old_launch_name'].startswith('user_defined_')) launch_config = xml_configs[3] if xml_configs[1] is None or xml_configs[0] is None: return {'status': 'fail', 'error_list': {'error': 'Please select the board info before this operation.'}} old_launch_name = launch_config_data['old_launch_name'] old_launch_path = os.path.join(current_app.config.get('CONFIG_PATH'), xml_configs[1], old_launch_name + '.xml') if launch_config_data['old_launch_name'].startswith('user_defined_'): old_launch_name = launch_config_data['old_launch_name'][13:] old_launch_path = os.path.join(current_app.config.get('CONFIG_PATH'), xml_configs[1], 'user_defined', old_launch_name + '.xml') launch_config.set_curr(old_launch_name) for key in launch_config_data: if key not in ['old_launch_name', 'new_launch_name', 'board_info_file', 'board_info_upload', 'scenario_name']: if isinstance(launch_config_data[key], list): launch_config.set_curr_list(launch_config_data[key], *tuple(key.split(','))) else: launch_config.set_curr_value(launch_config_data[key], *tuple(key.split(','))) scenario_name = launch_config_data['scenario_name'] scenario_file_path = os.path.join(current_app.config.get('CONFIG_PATH'), current_app.config.get('BOARD_TYPE'), scenario_name + '.xml') if launch_config_data['scenario_name'].startswith('user_defined_'): scenario_name = launch_config_data['scenario_name'][13:] scenario_file_path = os.path.join(current_app.config.get('CONFIG_PATH'), current_app.config.get('BOARD_TYPE'), 'user_defined', scenario_name + '.xml') launch_config.set_curr_attr('scenario', scenario_name) tmp_launch_file = os.path.join(current_app.config.get('CONFIG_PATH'), xml_configs[1], 'user_defined', 'tmp_' + launch_config_data['new_launch_name'] + '.xml') # if os.path.isfile(tmp_launch_file): # os.remove(tmp_launch_file) launch_config.save('tmp_' + launch_config_data['new_launch_name']) # call validate function rename = False try: (error_list, pthru_sel, virtio, dm_value) = validate_launch_setting( os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', xml_configs[0]+'.xml'), scenario_file_path, tmp_launch_file) print(pthru_sel, virtio, dm_value) except Exception as error: if os.path.isfile(tmp_launch_file): os.remove(tmp_launch_file) return {'status': 'fail', 'file_name': launch_config_data['new_launch_name'], 'rename': rename, 'error_list': {'launch config error': str(error)}} print('error_list: ', error_list) if not error_list: new_launch_path = os.path.join(current_app.config.get('CONFIG_PATH'), xml_configs[1], 'user_defined', launch_config_data['new_launch_name'] + '.xml') # check name conflict if old_launch_path != new_launch_path and os.path.isfile(new_launch_path): launch_config_data['new_launch_name'] = launch_config_data['new_launch_name'] \ + '_' + datetime.now().strftime('%Y%m%d%H%M%S') rename = True if os.path.isfile(old_launch_path) \ and launch_config_data['old_launch_name'].startswith('user_defined_'): os.remove(old_launch_path) launch_config.save(launch_config_data['new_launch_name']) if os.path.isfile(tmp_launch_file): os.remove(tmp_launch_file) return {'status': 'success', 'file_name': launch_config_data['new_launch_name'], 'rename': rename, 'error_list': error_list} @CONFIG_APP.route('/remove_setting', methods=['POST']) def remove_setting(): """ remove current setting from config app :return: the return message """ remove_config_data = request.json if request.method == "POST" else request.args print("*"*100+"remove_setting") print(remove_config_data) old_setting_name = remove_config_data['old_setting_name'] if current_app.config.get('BOARD_TYPE') is None: return {'status': 'Board info not set before remove current setting'} print(current_app.config.get('CONFIG_PATH'), current_app.config.get('BOARD_TYPE')) old_setting_path = os.path.join(current_app.config.get('CONFIG_PATH'), current_app.config.get('BOARD_TYPE'), old_setting_name+'.xml') if old_setting_name.startswith('user_defined_'): old_setting_path = os.path.join(current_app.config.get('CONFIG_PATH'), current_app.config.get('BOARD_TYPE'), 'user_defined', old_setting_name[13:] + '.xml') if os.path.isfile(old_setting_path): os.remove(old_setting_path) return {'status': 'success'} @CONFIG_APP.route('/generate_src', methods=['POST']) def generate_src(): """ generate board src or scenario src :return: the error message """ generator_config_data = request.json if request.method == "POST" else request.args print("generate_src") print(generator_config_data) src_type = generator_config_data['type'] board_info = generator_config_data['board_info'] board_type = current_app.config.get('BOARD_TYPE') board_info_xml = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', board_info+'.xml') scenario_setting = generator_config_data['scenario_setting'] scenario_setting_xml = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', scenario_setting+'.xml') launch_setting_xml = None if 'launch_setting' in generator_config_data: launch_setting = generator_config_data['launch_setting'] launch_setting_xml = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', launch_setting + '.xml') msg = {} error_list = {} status = 'success' if src_type == 'generate_config_src': try: from board_config.board_cfg_gen import ui_entry_api error_list = ui_entry_api(board_info_xml, scenario_setting_xml) except Exception as error: status = 'fail' error_list = {'board setting error': str(error)} try: from scenario_config.scenario_cfg_gen import ui_entry_api error_list = ui_entry_api(board_info_xml, scenario_setting_xml) except Exception as error: status = 'fail' error_list = {'scenario setting error': str(error)} elif src_type == 'generate_launch_script': if scenario_setting.startswith('user_defined_'): scenario_setting = scenario_setting[13:] scenario_setting_xml = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', scenario_setting + '.xml') else: scenario_setting_xml = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, scenario_setting + '.xml') try: from launch_config.launch_cfg_gen import ui_entry_api error_list = ui_entry_api(board_info_xml, scenario_setting_xml, launch_setting_xml) except Exception as error: status = 'fail' error_list = {'launch setting error': str(error)} else: status = 'fail' error_list = {'error': 'generator type not specified'} msg = {'status': status, 'error_list': error_list} print(msg) return msg @CONFIG_APP.route('/upload_board_info', methods=['POST']) def upload_board_info(): """ upload board info xml file :return: the upload status """ if request.method == 'POST': if 'file' not in request.files: return {'status': 'Error: no file uploaded'} file = request.files['file'] if file and '.' in file.filename and file.filename.rsplit('.', 1)[1] in ['xml']: filename = secure_filename(file.filename) tmp_filename = 'tmp_' + filename save_tmp_board_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', tmp_filename) file.save(save_tmp_board_path) board_type_list = [] config_path = current_app.config.get('CONFIG_PATH') for config_name in os.listdir(config_path): if os.path.isdir(os.path.join(config_path, config_name)) \ and config_name != 'generic': board_type_list.append(config_name) res_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res') if not os.path.isdir(res_path): os.makedirs(res_path) board_info_config = XmlConfig(res_path) board_info_config.set_curr(tmp_filename.rsplit('.', 1)[0]) board_info_root = board_info_config.get_curr_root() board_type = None if board_info_root and 'board' in board_info_root.attrib \ and 'scenario' not in board_info_root.attrib \ and 'uos_launcher' not in board_info_root.attrib: board_type = board_info_root.attrib['board'] if not board_type: os.remove(save_tmp_board_path) return {'status': 'Error on parsing Board info\n' 'check the xml syntax and whether there is only the board ' 'attribute in the board info file'} os.rename(save_tmp_board_path, os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res', filename)) info = 'updated' if board_type not in board_type_list: info = board_type os.makedirs(os.path.join(config_path, board_type)) for generic_name in os.listdir(os.path.join(config_path, 'generic')): generic_file = os.path.join(config_path, 'generic', generic_name) if os.path.isfile(generic_file): new_file = os.path.join(config_path, board_type, generic_name) copyfile(generic_file, new_file) xml_config = XmlConfig(os.path.join(current_app.config.get('CONFIG_PATH'), board_type)) xml_config.set_curr(generic_name[:-4]) xml_config.set_curr_attr('board', board_type) xml_config.save(generic_name[:-4], user_defined=False) board_info = os.path.splitext(file.filename)[0] current_app.config.update(BOARD_INFO=board_info) current_app.config.update(BOARD_TYPE=board_type) return {'status': 'success', 'info': info} return {'status': 'Error: upload failed'} @CONFIG_APP.route('/select_board', methods=['POST']) def select_board(): """ select one board info :return: the selected board info """ data = request.json if request.method == "POST" else request.args board_info = data['board_info'] current_app.config.update(BOARD_INFO=board_info) board_type = get_board_info_type(board_info) current_app.config.update(BOARD_TYPE=board_type) if board_type: return board_type return '' @CONFIG_APP.route('/upload_scenario', methods=['POST']) def upload_scenario(): """ upload scenario setting xml file :return: the upload status """ if request.method == 'POST': if 'file' not in request.files: return {'status': 'no file uploaded'} file = request.files['file'] if file and '.' in file.filename and file.filename.rsplit('.', 1)[1] in ['xml']: filename = secure_filename(file.filename) print(filename) scenario_file_name = os.path.splitext(file.filename)[0] board_type = current_app.config.get('BOARD_TYPE') tmp_scenario_name = 'tmp_' + scenario_file_name + '.xml' tmp_scenario_file = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', tmp_scenario_name) tmp_scenario_folder = os.path.dirname(tmp_scenario_file) if not os.path.exists(tmp_scenario_folder): os.makedirs(tmp_scenario_folder) if os.path.isfile(tmp_scenario_file): os.remove(tmp_scenario_file) file.save(tmp_scenario_file) tmp_xml_config = XmlConfig(os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined')) tmp_xml_config.set_curr(tmp_scenario_name[:-4]) status = None if tmp_xml_config.get_curr_root() is None: status = 'Error on parsing the scenario xml file, \n' \ 'check the xml syntax and config items.' else: tmp_root = tmp_xml_config.get_curr_root() if 'board' not in tmp_root.attrib or 'scenario' not in tmp_root.attrib \ or 'uos_launcher' in tmp_root.attrib: status = 'Invalid scenario xml file, \nonly board and scenario ' \ 'need to be configured.' elif tmp_root.attrib['board'] != current_app.config.get('BOARD_TYPE'): status = 'Current board: {} mismatched with the board in the scenario file,' \ '\nplease reselect or upload the board info: {}'\ .format(current_app.config.get('BOARD_TYPE'), tmp_root.attrib['board']) if status is not None: if os.path.isfile(tmp_scenario_file): os.remove(tmp_scenario_file) return {'status': status} error_list = {} new_scenario_name = scenario_file_name rename = False if not error_list: new_scenario_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', scenario_file_name + '.xml') if os.path.isfile(new_scenario_path): new_scenario_name = new_scenario_name + '_' \ + datetime.now().strftime('%Y%m%d%H%M%S') rename = True os.rename(tmp_scenario_file, os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', new_scenario_name + '.xml')) return {'status': 'success', 'file_name': new_scenario_name, 'rename': rename, 'error_list': error_list} return {'status': 'unsupported method'} @CONFIG_APP.route('/upload_launch', methods=['POST']) def upload_launch(): """ upload scenario setting xml file :return: the upload status """ if request.method == 'POST': if 'file' not in request.files: return {'status': 'no file uploaded'} file = request.files['file'] if file and '.' in file.filename and file.filename.rsplit('.', 1)[1] in ['xml']: filename = secure_filename(file.filename) print(filename) launch_file_name = os.path.splitext(file.filename)[0] board_type = current_app.config.get('BOARD_TYPE') tmp_launch_name = 'tmp_' + launch_file_name + '.xml' tmp_launch_file = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', tmp_launch_name) if os.path.isfile(tmp_launch_file): os.remove(tmp_launch_file) file.save(tmp_launch_file) tmp_xml_config = XmlConfig(os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined')) tmp_xml_config.set_curr(tmp_launch_name[:-4]) status = None if tmp_xml_config.get_curr_root() is None: status = 'Error on parsing the scenario xml file, \n' \ 'check the xml syntax and config items.' else: tmp_root = tmp_xml_config.get_curr_root() if 'board' not in tmp_root.attrib or 'scenario' not in tmp_root.attrib \ or 'uos_launcher' not in tmp_root.attrib: status = 'Invalid launch xml file, \nboard, scenario,' \ 'and uos_launcher need to be configured.' elif tmp_root.attrib['board'] != current_app.config.get('BOARD_TYPE'): status = 'Current board: {} mismatched with the board in the launch file,' \ '\nplease reselect or upload the board info: {}' \ .format(current_app.config.get('BOARD_TYPE'), tmp_root.attrib['board']) if status is not None: if os.path.isfile(tmp_launch_file): os.remove(tmp_launch_file) return {'status': status} error_list = {} new_launch_name = launch_file_name rename = False if not error_list: new_launch_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', launch_file_name + '.xml') if os.path.isfile(new_launch_path): new_launch_name = new_launch_name + '_' + \ datetime.now().strftime('%Y%m%d%H%M%S') rename = True os.rename(tmp_launch_file, os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined', new_launch_name + '.xml')) return {'status': 'success', 'file_name': new_launch_name, 'rename': rename, 'error_list': error_list} return {'status': 'unsupported method'} def get_board_list(): """ get all available board info files :return: the file list of board info """ res_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res') if not os.path.isdir(res_path): os.makedirs(res_path) board_info_list = [] for file in os.listdir(res_path): if os.path.isfile(os.path.join(res_path, file)) and \ '.' in file and file.rsplit('.', 1)[1] in ['xml']: board_info_list.append(file.rsplit('.', 1)[0]) return board_info_list def get_xml_configs(user_defined=False): """ get xml config related variables :return: board_info, board_config, scenario_config, launch_config """ config_path = None board_info = current_app.config.get('BOARD_INFO') board_type = get_board_info_type(board_info) if board_type is not None: config_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type) if user_defined: scenario_config = XmlConfig(config_path, False) launch_config = XmlConfig(config_path, False) else: scenario_config = XmlConfig(config_path) launch_config = XmlConfig(config_path) return board_info, board_type, scenario_config, launch_config def get_generic_scenario_config(scenario_config): config_path = os.path.join(current_app.config.get('CONFIG_PATH'), 'generic') generic_scenario_config = XmlConfig(config_path) for file in os.listdir(config_path): if os.path.isfile(os.path.join(config_path, file)) and \ os.path.splitext(file)[1] == '.xml': generic_scenario_config.set_curr(os.path.splitext(file)[0]) generic_scenario_config_root = generic_scenario_config.get_curr_root() if 'scenario' in generic_scenario_config_root.attrib \ and 'uos_launcher' not in generic_scenario_config_root.attrib \ and generic_scenario_config_root.attrib['scenario'] == \ scenario_config.get_curr_root().attrib['scenario']: return generic_scenario_config return None def get_board_info_type(board_info): """ get board info type :param board_info: the board info file :return: the board type """ board_type = None if board_info is not None: board_info_config = XmlConfig(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'res')) board_info_config.set_curr(board_info) board_info_root = board_info_config.get_curr_root() if board_info_root and 'board' in board_info_root.attrib: board_type = board_info_root.attrib['board'] return board_type