mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-20 20:53:46 +00:00
acrn-config: add RDT support in scenario config of config app
RDT config item is located in the 5rd layer of scenario config; the number of CLOS_MASK config is dynamically obtained by the rdt resource clos max in the board config; the vcpu_clos config is dynamically added or removed when the pcpu_id config is added or removed; the drop-down list of vcpu_clos config is reduced by half when CDP_ENABLED=y. Tracked-On: #4860 Signed-off-by: Shuang Zheng <shuang.zheng@intel.com> Reviewed-by: Victor Sun <victor.sun@intel.com>
This commit is contained in:
parent
6ed2b855bf
commit
93b12818c7
@ -208,6 +208,18 @@ class XmlConfig:
|
||||
new_node = ElementTree.SubElement(dest_node, key, attrib={'desc': desc})
|
||||
new_node.text = value
|
||||
|
||||
def get_curr_elem(self, *args):
|
||||
"""
|
||||
get elements for current path.
|
||||
:param args: the path of the element.
|
||||
:return: current element.
|
||||
"""
|
||||
if self._curr_xml_tree is None:
|
||||
return
|
||||
|
||||
dest_node = self._get_dest_node(*args)
|
||||
return dest_node
|
||||
|
||||
def clone_curr_elem(self, elem, *args):
|
||||
"""
|
||||
clone elements for current path.
|
||||
@ -235,6 +247,18 @@ class XmlConfig:
|
||||
dest_node = self._get_dest_node(*args)
|
||||
dest_node.insert(index, elem)
|
||||
|
||||
def delete_curr_elem(self, *args):
|
||||
"""
|
||||
delete the element by its path.
|
||||
:param args: the path of the element.
|
||||
:return: None.
|
||||
"""
|
||||
if self._curr_xml_tree is None:
|
||||
return
|
||||
father_node = self._get_dest_node(*args[:-1])
|
||||
dest_node = self._get_dest_node(*args)
|
||||
father_node.remove(dest_node)
|
||||
|
||||
def delete_curr_key(self, *args):
|
||||
"""
|
||||
delete the element by its path.
|
||||
|
@ -401,6 +401,18 @@ $().ready(function(){
|
||||
show_com_target(id, value);
|
||||
});
|
||||
|
||||
$("select[ID$='FEATURES,RDT,CDP_ENABLED']").change(function(){
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).val();
|
||||
update_vcpu_clos_option(id, value);
|
||||
});
|
||||
|
||||
$("select[ID$='FEATURES,RDT,CDP_ENABLED']").each(function(index, item) {
|
||||
var id = $(this).attr('id');
|
||||
var value = $(item).val();
|
||||
update_vcpu_clos_option(id, value);
|
||||
});
|
||||
|
||||
$(document).on('click', "button:contains('+')", function() {
|
||||
if($(this).text() != '+')
|
||||
return;
|
||||
@ -408,7 +420,21 @@ $().ready(function(){
|
||||
var curr_id = curr_item_id.substr(curr_item_id.lastIndexOf('_')+1);
|
||||
var config_item = $(this).parent().parent();
|
||||
var config_item_added = config_item.clone();
|
||||
var id_added = (parseInt(curr_id)+1).toString();
|
||||
var config_vm = config_item.parent();
|
||||
var vcpu_index_list = [];
|
||||
config_vm.children().each(function(){
|
||||
if($(this).find("button:contains('+')").size() > 0) {
|
||||
var btn_add_vm_id = $(this).find("button:contains('+')").attr('id');
|
||||
vcpu_index_list.push(parseInt(btn_add_vm_id.substr(btn_add_vm_id.lastIndexOf('_')+1)));
|
||||
}
|
||||
});
|
||||
var id_added = 0;
|
||||
for (i=0; i<100; i++) {
|
||||
if (!vcpu_index_list.includes(i)) {
|
||||
id_added = i;
|
||||
break
|
||||
}
|
||||
}
|
||||
var id_pre_added = curr_item_id.substr(0, curr_item_id.lastIndexOf('_'));
|
||||
config_item_added.find("button:contains('+')").attr('id', id_pre_added+'_'+id_added);
|
||||
config_item_added.find("button:contains('-')").attr('id', id_pre_added.replace('add_', 'remove_')+'_'+id_added);
|
||||
@ -418,12 +444,50 @@ $().ready(function(){
|
||||
config_item_added.find('.selectpicker').val('default').selectpicker('deselectAll');;
|
||||
config_item_added.find('.selectpicker').selectpicker('render');
|
||||
config_item_added.insertAfter(config_item);
|
||||
|
||||
if(curr_item_id.indexOf('add_vcpu')>=0) {
|
||||
var config_vm = config_item.parent();
|
||||
var curr_vcpu_index = vcpu_index_list.indexOf(parseInt(curr_id))
|
||||
var vcpu_clos_item = config_vm.find("label:contains('vcpu_clos')").first().parent();
|
||||
while(curr_vcpu_index > 0) {
|
||||
vcpu_clos_item = vcpu_clos_item.next();
|
||||
curr_vcpu_index -= 1;
|
||||
}
|
||||
|
||||
var vcpu_clos_item_added = vcpu_clos_item.clone();
|
||||
vcpu_clos_item_added.find("label:first").text("");
|
||||
vcpu_clos_item_added.find('.bootstrap-select').replaceWith(function() { return $('select', this); });
|
||||
vcpu_clos_item_added.find('.selectpicker').val('default').selectpicker('deselectAll');;
|
||||
vcpu_clos_item_added.find('.selectpicker').selectpicker('render');
|
||||
vcpu_clos_item_added.insertAfter(vcpu_clos_item);
|
||||
}
|
||||
});
|
||||
|
||||
$(document).on('click', "button:contains('-')", function() {
|
||||
if($(this).text() != '-')
|
||||
return;
|
||||
var config_item = $(this).parent().parent();
|
||||
var curr_item_id = $(this).attr('id');
|
||||
if(curr_item_id.indexOf('remove_vcpu')>=0) {
|
||||
var config_vm = config_item.parent();
|
||||
var vcpu_index_list = [];
|
||||
config_vm.children().each(function(){
|
||||
if($(this).find("button:contains('+')").size() > 0) {
|
||||
var btn_del_vm_id = $(this).find("button:contains('+')").attr('id');
|
||||
vcpu_index_list.push(parseInt(btn_del_vm_id.substr(btn_del_vm_id.lastIndexOf('_')+1)));
|
||||
}
|
||||
});
|
||||
var curr_item_id = $(this).attr('id');
|
||||
var curr_id = parseInt(curr_item_id.substr(curr_item_id.lastIndexOf('_')+1));
|
||||
curr_vcpu_index = vcpu_index_list.indexOf(curr_id);
|
||||
|
||||
var vcpu_clos_item = config_vm.find("label:contains('vcpu_clos')").first().parent();
|
||||
while(curr_vcpu_index > 0) {
|
||||
vcpu_clos_item = vcpu_clos_item.next();
|
||||
curr_vcpu_index -= 1;
|
||||
}
|
||||
vcpu_clos_item.remove();
|
||||
}
|
||||
config_item.remove();
|
||||
});
|
||||
|
||||
@ -472,6 +536,35 @@ function show_com_target(id, value) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function update_vcpu_clos_option(id, value) {
|
||||
if(value == 'y') {
|
||||
$("select[ID$='clos,vcpu_clos']").each(function(){
|
||||
len = $(this).find('option').length;
|
||||
option = $(this).find('option').first();
|
||||
for(i=0; i<len; i++){
|
||||
if(i>(len-1)/2){
|
||||
option.attr('disabled','disabled');
|
||||
}
|
||||
option = option.next();
|
||||
}
|
||||
$(this).selectpicker('render');
|
||||
});
|
||||
} else {
|
||||
$("select[ID$='clos,vcpu_clos']").each(function(){
|
||||
len = $(this).find('option').length;
|
||||
option = $(this).find('option').first();
|
||||
for(i=0; i<len; i++){
|
||||
if(i>(len-1)/2){
|
||||
option.removeAttr('disabled');
|
||||
}
|
||||
option = option.next();
|
||||
}
|
||||
$(this).selectpicker('render');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function create_setting(type, default_name, name, mode){
|
||||
var board_info = $("text#board_type").text();
|
||||
if (board_info==null || board_info=='') {
|
||||
@ -570,7 +663,13 @@ function save_scenario(generator=null){
|
||||
$("input").each(function(){
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).val();
|
||||
if(id!='new_scenario_name' && id!='new_scenario_name2' && id!='board_info_file' && id!='board_info_upload'
|
||||
if(id.indexOf('CLOS_MASK')>=0 ) {
|
||||
if(id in scenario_config) {
|
||||
scenario_config[id].push(value);
|
||||
} else {
|
||||
scenario_config[id] = [value];
|
||||
}
|
||||
} else if(id!='new_scenario_name' && id!='new_scenario_name2' && id!='board_info_file' && id!='board_info_upload'
|
||||
&& id!='scenario_file' && id!='create_name' && id!='load_scenario_name2' && id!='load_launch_name2'
|
||||
&& id!='src_path') {
|
||||
scenario_config[id] = value;
|
||||
@ -586,7 +685,7 @@ function save_scenario(generator=null){
|
||||
$("select").each(function(){
|
||||
var id = $(this).attr('id');
|
||||
var value = $(this).val();
|
||||
if(id.indexOf('pcpu_id')>=0 || id.indexOf('pci_dev')>=0) {
|
||||
if(id.indexOf('pcpu_id')>=0 || id.indexOf('pci_dev')>=0 || id.indexOf('vcpu_clos')>=0) {
|
||||
if(id in scenario_config) {
|
||||
scenario_config[id].push(value);
|
||||
} else {
|
||||
|
@ -179,7 +179,7 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<label class="col-sm-1 control-label"> Board type:</label>
|
||||
<label class="col-sm-1 control-label"> Board name:</label>
|
||||
<text class="col-sm-2 control-label" id="board_type" style="text-align: left;">{{board_type if board_type != None else ''}}</text>
|
||||
<div class="col-sm-6">
|
||||
<form action="" enctype="multipart/form-data" method='POST'>
|
||||
|
@ -210,6 +210,76 @@ the source files will be generated into default path and overwirte the previous
|
||||
{% set first_child = [] %}
|
||||
{% for sub_elem in elem.getchildren() %}
|
||||
{% set sub_elem_text = sub_elem.text if sub_elem.text != None else '' %}
|
||||
|
||||
{% if sub_elem.tag == 'RDT' %}
|
||||
{% for sub_elem_2 in sub_elem.getchildren() %}
|
||||
{% if ','.join([vm.tag, elem.tag, sub_elem.tag, sub_elem_2.tag]) not in scenario_item_values %}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{elem.attrib['desc'] if 'desc' in elem.attrib else elem.tag}}">
|
||||
</label>
|
||||
<label class="col-sm-2 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem_2.attrib['desc'] if 'desc' in sub_elem_2.attrib else sub_elem.attrib['desc']}}">
|
||||
{{sub_elem.tag}} {{sub_elem_2.tag}}</label>
|
||||
<div class="col-sm-6">
|
||||
{% if 'readonly' in sub_elem_2.attrib and sub_elem_2.attrib['readonly'] == 'true' %}
|
||||
<input type="text" class="form-control"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}"
|
||||
readonly vaule={{sub_elem_2.text}}></input>
|
||||
{% else %}
|
||||
<input type="text" class="form-control"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}" value={{sub_elem_2.text}}></input>
|
||||
{% endif %}
|
||||
</div>
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}_err" class="col-sm-3"></p>
|
||||
</div>
|
||||
{% elif sub_elem_2.tag != 'CLOS_MASK' %}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{elem.attrib['desc'] if 'desc' in elem.attrib else elem.tag}}">
|
||||
</label>
|
||||
<label class="col-sm-2 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem_2.attrib['desc'] if 'desc' in sub_elem_2.attrib else sub_elem.attrib['desc']}}">
|
||||
{{sub_elem.tag}} {{sub_elem_2.tag}}</label>
|
||||
<div class="dropdown col-sm-6">
|
||||
{% if 'readonly' in sub_elem_2.attrib and sub_elem_2.attrib['readonly'] == 'true' %}
|
||||
<select class="selectpicker" data-width="auto"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}" disabled>
|
||||
{% else %}
|
||||
<select class="selectpicker" data-width="auto"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}">
|
||||
{% endif %}
|
||||
<option disabled selected value> -- Select an option -- </option>
|
||||
{% for item_value in scenario_item_values[vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag] %}
|
||||
{% if item_value == sub_elem_2.text %}
|
||||
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
|
||||
{% else %}
|
||||
<option value="{{item_value}}">{{item_value}}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}_err" class="col-sm-3"></p>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="form-group">
|
||||
<label class="col-sm-1 control-label" data-toggle="tooltip"
|
||||
title="{{elem.attrib['desc'] if 'desc' in elem.attrib else elem.tag}}">
|
||||
</label>
|
||||
<label class="col-sm-2 control-label" data-toggle="tooltip"
|
||||
title={{sub_elem_2.attrib['desc'] if 'desc' in sub_elem_2.attrib else sub_elem.attrib['desc']}}>
|
||||
{{sub_elem.tag}} {{sub_elem_2.tag}}</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="text" class="form-control"
|
||||
id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}" value={{sub_elem_2.text}}></input>
|
||||
</div>
|
||||
<p id="{{vm_type+','+elem.tag+','+sub_elem.tag+','+sub_elem_2.tag}}_err" class="col-sm-3"></p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% else %}
|
||||
|
||||
{% if 'configurable' not in sub_elem.attrib or sub_elem.attrib['configurable'] != '0' %}
|
||||
<div class="form-group">
|
||||
{% if 'id' not in elem.attrib %}
|
||||
@ -222,6 +292,7 @@ the source files will be generated into default path and overwirte the previous
|
||||
title="{{elem.attrib['desc'] if 'desc' in elem.attrib else elem.tag}}">
|
||||
</label>
|
||||
{% endif %}
|
||||
|
||||
<label class="col-sm-2 control-label" data-toggle="tooltip"
|
||||
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
|
||||
{{sub_elem.tag}}</label>
|
||||
@ -353,6 +424,7 @@ the source files will be generated into default path and overwirte the previous
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% elif 'configurable' not in elem.attrib or elem.attrib['configurable'] != '0' %}
|
||||
<div class="form-group">
|
||||
|
@ -147,7 +147,6 @@ def save_scenario():
|
||||
:return: the error list for the edited scenario setting.
|
||||
"""
|
||||
scenario_config_data = request.json if request.method == "POST" else request.args
|
||||
|
||||
xml_configs = get_xml_configs()
|
||||
board_type = xml_configs[1]
|
||||
scenario_config = xml_configs[3]
|
||||
@ -426,6 +425,7 @@ def create_setting():
|
||||
create_name = create_config_data['create_name']
|
||||
|
||||
xml_configs = get_xml_configs(True)
|
||||
board_info = xml_configs[0]
|
||||
board_type = xml_configs[1]
|
||||
scenario_config = xml_configs[2]
|
||||
launch_config = xml_configs[3]
|
||||
@ -470,7 +470,16 @@ def create_setting():
|
||||
copyfile(src_file_name,
|
||||
os.path.join(current_app.config.get('CONFIG_PATH'), board_type, 'user_defined',
|
||||
create_name + '.xml'))
|
||||
|
||||
if mode == 'create':
|
||||
# update RDT->CLOS_MASK according to board xml
|
||||
scenario_config.set_curr(create_name)
|
||||
rdt_clos_max = get_board_rdt_clos_max(board_info)
|
||||
elem_clos_max = scenario_config.get_curr_elem('hv', 'FEATURES', 'RDT', 'CLOS_MASK')
|
||||
if rdt_clos_max > 0:
|
||||
for i in range(rdt_clos_max - 1):
|
||||
scenario_config.clone_curr_elem(elem_clos_max, 'hv', 'FEATURES', 'RDT')
|
||||
else:
|
||||
scenario_config.delete_curr_elem('hv', 'FEATURES', 'RDT', 'CLOS_MASK')
|
||||
scenario_config.save(create_name)
|
||||
return {'status': 'success', 'setting': create_name, 'error_list': {}}
|
||||
|
||||
@ -616,6 +625,17 @@ def upload_board_info():
|
||||
board_type))
|
||||
xml_config.set_curr(generic_name[:-4])
|
||||
xml_config.set_curr_attr('board', board_type)
|
||||
# update RDT->CLOS_MASK according to board xml
|
||||
xml_config_root = xml_config.get_curr_root()
|
||||
if 'board' in xml_config_root.attrib and 'scenario' in xml_config_root.attrib \
|
||||
and 'uos_launcher' not in xml_config_root.attrib:
|
||||
rdt_clos_max = get_board_rdt_clos_max(filename.rsplit('.', 1)[0])
|
||||
elem_clos_max = xml_config.get_curr_elem('hv', 'FEATURES', 'RDT', 'CLOS_MASK')
|
||||
if rdt_clos_max > 0:
|
||||
for i in range(rdt_clos_max-1):
|
||||
xml_config.clone_curr_elem(elem_clos_max, 'hv', 'FEATURES', 'RDT')
|
||||
else:
|
||||
xml_config.delete_curr_elem('hv', 'FEATURES', 'RDT', 'CLOS_MASK')
|
||||
xml_config.save(generic_name[:-4], user_defined=False)
|
||||
|
||||
board_info = os.path.splitext(file.filename)[0]
|
||||
@ -924,7 +944,7 @@ def get_board_info(board_info):
|
||||
"""
|
||||
get board info type
|
||||
:param board_info: the board info file
|
||||
:return: the board type
|
||||
:return: the board info
|
||||
"""
|
||||
board_config = get_board_config(board_info)
|
||||
bios_info = None
|
||||
@ -951,6 +971,32 @@ def get_board_info(board_info):
|
||||
return (bios_info, base_board_info)
|
||||
|
||||
|
||||
def get_board_rdt_clos_max(board_info):
|
||||
"""
|
||||
get board info type
|
||||
:param board_info: the board info file
|
||||
:return: the rdt clos max
|
||||
"""
|
||||
board_config = get_board_config(board_info)
|
||||
rdt_clos_max = 0
|
||||
|
||||
if board_config is not None:
|
||||
board_info_root = board_config.get_curr_root()
|
||||
if board_info_root:
|
||||
for item in board_info_root.getchildren():
|
||||
if item.tag == 'CLOS_INFO':
|
||||
for line in item.text.split('\n'):
|
||||
line = line.strip()
|
||||
if line.startswith('rdt resource clos max:'):
|
||||
try:
|
||||
rdt_clos_max = int(line.split(':')[1].strip())
|
||||
break
|
||||
except:
|
||||
pass
|
||||
|
||||
return rdt_clos_max
|
||||
|
||||
|
||||
def assign_vm_id(scenario_config):
|
||||
"""
|
||||
assign vm ids for the scenario setting.
|
||||
|
Loading…
Reference in New Issue
Block a user