acrn-config: add PCI VUART config in scenario config UI

Add PCI VUART dynamic config for VMs in scenario config UI, keep legacy
VUART config. PCI vuart base can be set to INVALID_PCI_BASE and PCI_VUART;
users will configure the target_vm_id and target_vuart_id when PCI vuart
base is set to PCI_VUART; users can dynamically add or delete PCI vuart
for VMs.

Tracked-On: #5394

Signed-off-by: Shuang Zheng <shuang.zheng@intel.com>
This commit is contained in:
Shuang Zheng 2020-10-20 18:53:09 +08:00 committed by wenlingz
parent d55dd1c0b9
commit 788f28035d
4 changed files with 147 additions and 12 deletions

View File

@ -401,6 +401,18 @@ $().ready(function(){
show_com_target(id, value);
});
$(document).on('change', "select[ID*='communication_vuart'][ID$='base']", function() {
var id = $(this).attr('id');
var value = $(this).val();
show_com_target(id, value);
});
$("select[ID*='communication_vuart'][ID$='base']").each(function(index, item) {
var id = $(item).attr('id');
var value = $(item).val();
show_com_target(id, value);
});
$("select[ID$='FEATURES,RDT,CDP_ENABLED']").change(function(){
var id = $(this).attr('id');
var value = $(this).val();
@ -424,30 +436,70 @@ $().ready(function(){
var config_item_added = config_item.clone();
var config_vm = config_item.parent();
var vcpu_index_list = [];
var vuart_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)));
if(btn_add_vm_id.indexOf('add_communication_vuart')>=0) {
vuart_index_list.push(parseInt(btn_add_vm_id.substr(btn_add_vm_id.lastIndexOf('_')+1)));
} else {
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_added = -1;
if(curr_item_id.indexOf('add_communication_vuart')>=0) {
for (i=1; i<100; i++) {
if (!vuart_index_list.includes(i)) {
id_added = i;
break
}
}
} else {
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);
var curr_err_id = config_item_added.find("p").attr('id');
config_item_added.find("p").attr('id', curr_err_id.replace(','+curr_id+'_', ','+id_added+'_'));
config_item_added.find("button:contains('-')").prop("disabled", false);
config_item_added.find("label:first").text("");
config_item_added.find('.bootstrap-select').replaceWith(function() { return $('select', this); });
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_communication_vuart')>=0) {
var config_item_target_vm = config_item.next().clone();
var config_item_target_vuart = config_item.next().next().clone();
var curr_vuart_id = parseInt(curr_id);
config_item_added.find("label:first").text(config_item_added.find("label:first").html().replace(curr_vuart_id, id_added));
var orig_id_list = ['base_label1', 'base_label2', 'base', 'base_err',
'target_vm_id_label1', 'target_vm_id_label2', 'target_vm_id_config', 'target_vm_id', 'target_vm_id_err',
'target_uart_id_label1', 'target_uart_id_label2', 'target_uart_id_config', 'target_uart_id', 'target_uart_id_err']
for(var i = 0, len = 4; i < len; i++){
var orig_base_item = config_item_added.find('[id$='+orig_id_list[i]+']')
orig_base_item.attr('id', orig_base_item.attr('id').replace(curr_vuart_id+','+orig_id_list[i], id_added+','+orig_id_list[i]))
}
for(var i = 4, len = 9; i < len; i++){
var orig_target_vm_item = config_item_target_vm.find('[id$='+orig_id_list[i]+']')
orig_target_vm_item.attr('id', orig_target_vm_item.attr('id').replace(curr_vuart_id+','+orig_id_list[i], id_added+','+orig_id_list[i]))
}
for(var i = 9, len = orig_id_list.length; i < len; i++){
var orig_target_vuart_item = config_item_target_vuart.find('[id$='+orig_id_list[i]+']')
orig_target_vuart_item.attr('id', orig_target_vuart_item.attr('id').replace(curr_vuart_id+','+orig_id_list[i], id_added+','+orig_id_list[i]))
}
config_item_added.insertAfter(config_item.next().next());
config_item_target_vm.insertAfter(config_item_added);
config_item_target_vuart.insertAfter(config_item_target_vm);
} else {
config_item_added.find("label:first").text("");
config_item_added.insertAfter(config_item);
}
if(curr_item_id.indexOf('add_vcpu')>=0) {
var config_vm = config_item.parent();
@ -492,6 +544,10 @@ $().ready(function(){
}
vcpu_clos_item.remove();
}
else if(curr_item_id.indexOf('remove_communication_vuart')>=0) {
config_item.next().next().remove();
config_item.next().remove();
}
config_item.remove();
});
@ -520,11 +576,14 @@ function show_com_target(id, value) {
return
}
var id2 = id.replace('base', 'target_vm_id');
var id3 = id.replace('base', 'target_uart_id');
var jquerySpecialChars = ["~", "`", "@", "#", "%", "&", "=", "'", "\"",
":", ";", "<", ">", ",", "/"];
for (var i = 0; i < jquerySpecialChars.length; i++) {
id2 = id2.replace(new RegExp(jquerySpecialChars[i],
"g"), "\\" + jquerySpecialChars[i]);
id3 = id3.replace(new RegExp(jquerySpecialChars[i],
"g"), "\\" + jquerySpecialChars[i]);
}
if (value == 'INVALID_COM_BASE') {
$('#'+id2+'_label1').hide();
@ -532,6 +591,26 @@ function show_com_target(id, value) {
$('#'+id2+'_config').hide();
$('#'+id2+'_err').hide();
}
else if(value == 'INVALID_PCI_BASE') {
$('#'+id2+'_label1').hide();
$('#'+id2+'_label2').hide();
$('#'+id2+'_config').hide();
$('#'+id2+'_err').hide();
$('#'+id3+'_label1').hide();
$('#'+id3+'_label2').hide();
$('#'+id3+'_config').hide();
$('#'+id3+'_err').hide();
}
else if(value == 'PCI_VUART') {
$('#'+id2+'_label1').show();
$('#'+id2+'_label2').show();
$('#'+id2+'_config').show();
$('#'+id2+'_err').show();
$('#'+id3+'_label1').show();
$('#'+id3+'_label2').show();
$('#'+id3+'_config').show();
$('#'+id3+'_err').show();
}
else {
$('#'+id2+'_label1').show();
$('#'+id2+'_label2').show();

View File

@ -130,6 +130,7 @@ the source files will be generated into default path and overwirte the previous
{% if 'desc' in vm.attrib and vm.attrib['desc'] == 'specific for Kata' %}
{% do vm_kata.append(1) %}
{% endif %}
{% set first_multi_child = {'IVSHMEM_REGION': 0, 'communication_vuart': 1} %}
{% if 'configurable' not in vm.attrib or vm.attrib['configurable'] != '0'%}
<tr>
<td>
@ -209,7 +210,6 @@ the source files will be generated into default path and overwirte the previous
!= '0')%}
{% if 'multiselect' not in elem.attrib or elem.attrib['multiselect'] != 'true' %}
{% set first_child = [] %}
{% set first_multi_child = {'IVSHMEM_REGION': 0} %}
{% for sub_elem in elem.getchildren() %}
{% set sub_elem_text = sub_elem.text if sub_elem.text != None else '' %}
@ -392,7 +392,7 @@ the source files will be generated into default path and overwirte the previous
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
{{sub_elem.tag}}</label>
{% if (','.join([vm.tag, elem.tag, sub_elem.tag]) not in scenario_item_values) and
(elem.tag!='vuart' or sub_elem.tag!='base') %}
((elem.tag!='vuart' and elem.tag!='legacy_vuart') or sub_elem.tag!='base') %}
<div class="col-sm-6"
id="{{vm_type+','+elem.tag+':id='+elem.attrib['id']+','+sub_elem.tag}}_config">
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
@ -406,7 +406,9 @@ the source files will be generated into default path and overwirte the previous
{% endif %}
</div>
{% else %}
<div class="dropdown col-sm-6">
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
<select class="selectpicker" data-width="auto" disabled
id="{{vm_type+','+elem.tag+':id='+elem.attrib['id']+','+sub_elem.tag}}">
@ -415,7 +417,7 @@ the source files will be generated into default path and overwirte the previous
id="{{vm_type+','+elem.tag+':id='+elem.attrib['id']+','+sub_elem.tag}}">
{% endif %}
{% set key = ('vm='+vm.attrib['id']+','+elem.tag+'='+elem.attrib['id']+','+sub_elem.tag)
if (elem.tag=='vuart' and sub_elem.tag=='base')
if (elem.tag in ['vuart', 'legacy_vuart'] and sub_elem.tag=='base')
else ','.join([vm.tag, elem.tag, sub_elem.tag]) %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in scenario_item_values[key] %}
@ -426,6 +428,15 @@ the source files will be generated into default path and overwirte the previous
{% endif %}
{% endfor %}
</select>
{% if elem.tag in ['communication_vuart'] and sub_elem.tag in ['base'] %}
<button type="button" class="btn" id="add_{{elem.tag}}_{{first_multi_child[elem.tag]}}">+</button>
{% if first_multi_child[elem.tag] == 1 %}
<button type="button" disabled class="btn" id="remove_{{elem.tag}}_{{first_multi_child[elem.tag]}}">-</button>
{% else %}
<button type="button" class="btn" id="remove_{{elem.tag}}_{{first_multi_child[elem.tag]}}">-</button>
{% endif %}
{% do first_multi_child.update({elem.tag: first_multi_child[elem.tag]+1}) %}
{% endif%}
</div>
{% endif %}
<p id="{{vm_type+','+elem.tag+':id='+elem.attrib['id']+','+sub_elem.tag}}_err"

View File

@ -5,7 +5,7 @@
"""
import os
import os, copy
from datetime import datetime
from shutil import copyfile
@ -169,15 +169,51 @@ def save_scenario():
scenario_path = os.path.join(current_app.config.get('CONFIG_PATH'), board_type)
old_scenario_name = scenario_config_data['old_scenario_name']
scenario_config.set_curr(old_scenario_name)
for vm in scenario_config.get_curr_root().getchildren():
if vm.tag == 'vm':
for elem in vm.getchildren():
if elem.tag in ['communication_vuart', 'console_vuart']:
vuart_key = vm.tag+':id='+vm.attrib['id']+','+elem.tag + ':id='+elem.attrib['id']
delete_flag = True
for key in scenario_config_data:
if key.find(vuart_key) >= 0:
delete_flag = False
break
if delete_flag:
scenario_config.delete_curr_elem(*tuple(vuart_key.split(',')))
for key in scenario_config_data:
if scenario_config_data[key] in [None, 'None']:
scenario_config_data[key] = ''
if key not in ['old_scenario_name', 'new_scenario_name', 'generator', 'add_vm_type']:
if isinstance(scenario_config_data[key], list):
scenario_config.set_curr_list(scenario_config_data[key], *tuple(key.split(',')))
elif key.find('communication_vuart') >= 0:
try:
scenario_config.get_curr_elem(*tuple(key.split(',')))
except:
communication_vuart_id = key.split(',')[1].split('=')[1].strip()
communication_vuart_1_item = scenario_config.get_curr_elem(
*tuple([key.split(',')[0], 'communication_vuart:id=1']))
communication_vuart_i_item = copy.deepcopy(communication_vuart_1_item)
communication_vuart_i_item.attrib['id'] = communication_vuart_id
curr_index = 0
elem_list = scenario_config.get_curr_elem(key.split(',')[0]).getchildren()
for elem in reversed(elem_list):
curr_index += 1
if elem.tag in ['communication_vuart', 'console_vuart']:
break
scenario_config.insert_curr_elem(len(elem_list)-curr_index+1, communication_vuart_i_item, key.split(',')[0])
finally:
scenario_config.set_curr_value(scenario_config_data[key], *tuple(key.split(',')))
else:
scenario_config.set_curr_value(scenario_config_data[key], *tuple(key.split(',')))
# how to put added vuart under vuart!!!
# delete vuart without key!!!
generator = scenario_config_data['generator']
if generator is not None:
if generator == 'remove_vm_kata':
@ -1127,3 +1163,10 @@ def assign_vm_id(scenario_config):
elif item.text in ['POST_STD_VM', 'POST_RT_VM', 'KATA_VM']:
vm.attrib['id'] = str(post_launched_vm_index)
post_launched_vm_index += 1
@CONFIG_APP.context_processor
def utility_functions():
def print_in_console(message):
print(str(message))
return dict(mdebug=print_in_console)

View File

@ -58,6 +58,8 @@ def get_scenario_item_values(board_info, scenario_info):
scenario_item_values["vm,mmio_resources,p2sb"] = hv_cfg_lib.N_Y
scenario_item_values["vm,mmio_resources,TPM2"] = hv_cfg_lib.N_Y
scenario_item_values.update(scenario_cfg_lib.avl_vuart_ui_select(scenario_info))
scenario_item_values["vm,console_vuart,base"] = ['INVALID_PCI_BASE', 'PCI_VUART']
scenario_item_values["vm,communication_vuart,base"] = ['INVALID_PCI_BASE', 'PCI_VUART']
# board
(scenario_item_values["vm,board_private,rootfs"], num) = board_cfg_lib.get_rootfs(board_info)