acrn-config: dynamic configuration for scenario setting and launch setting

config app implements interfaces to dynamically:
    create new scenario settings based on tempaltes;
    create new launch settings based on templates;
    add or delete VMs for scenario settings;
    add or delete VMs for launch settings;
    load default scenario or launch settings

Tracked-On: #4641

Signed-off-by: Shuang Zheng <shuang.zheng@intel.com
Reviewed-by: Victor Sun <victor.sun@intel.com>
Acked-by: Terry Zou <terry.zou@intel.com>
This commit is contained in:
Shuang Zheng
2020-04-16 15:46:07 +08:00
committed by wenlingz
parent ccef1af1f0
commit b9ce7617cd
7 changed files with 1036 additions and 348 deletions

View File

@@ -15,6 +15,104 @@
</head>
<body>
<div class="modal fade" id="create_modal" tabindex="-1" role="dialog" aria-labelledby="createModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="createModalLabel"></h4>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="create_name" class="col-sm-3 control-label">Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="create_name"
value="">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="create_btn" data-id="" class="btn btn-primary">OK
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="load_scenario_modal" tabindex="-1" role="dialog" aria-labelledby="loadScenarioModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="loadScenarioModalLabel">Load Scenario Setting</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="load_scenario_name" class="col-sm-3 control-label">Default Scenario Setting: </label>
<div class="dropdown col-sm-6">
<select class="selectpicker" data-width="auto" id="load_scenario_name">
{% if scenarios[0] %}
{% for sc in scenarios[0] %}
<option value="{{sc}}">{{sc}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
<div class="form-group row">
<label for="load_scenario_name2" class="col-sm-3 control-label">Scenario Setting Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="load_scenario_name2"
value="{{scenarios[0][0] if scenarios[0] else ''}}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="load_scenario_btn" data-id="scenario" class="btn btn-primary">OK
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="load_launch_modal" tabindex="-1" role="dialog" aria-labelledby="loadLaunchModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="loadLaunchModalLabel">Load Launch setting</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="load_launch_name" class="col-sm-3 control-label">Default Launch Setting: </label>
<div class="dropdown col-sm-6">
<select class="selectpicker" data-width="auto" id="load_launch_name">
{% if launches[0] %}
{% for lc in launches[0] %}
<option value="{{lc}}">{{lc}}</option>
{% endfor %}
{% endif %}
</select>
</div>
</div>
<div class="form-group row">
<label for="load_launch_name2" class="col-sm-3 control-label">Launch Setting Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="load_launch_name2"
value="{{launches[0][0] if launches[0] else ''}}">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="load_launch_btn" data-id="launch" class="btn btn-primary">OK
</button>
</div>
</div>
</div>
</div>
<nav class="navbar navbar-inverse">
<div class="container-fluid">
<div class="navbar-header">
@@ -26,13 +124,13 @@
Scenario Setting <span class="caret"></span></a>
<ul class="dropdown-menu">
{% if scenarios[0] %}
<small class="text-muted">default</small>
{% for sc in scenarios[0] %}
<li><a href="{{ url_for('CONFIG_APP.scenario', scenario_name=sc) }}">{{sc}}</a></li>
{% endfor %}
<small class="text-muted">user-defined</small>
<li><a href="" data-toggle="modal" data-target="#create_modal" class="create_menu"
data-id="scenario">Create a new scenario</a></li>
<li><a href="" data-toggle="modal" data-target="#load_scenario_modal" class="load_menu"
data-id="scenario">Load a default scenario</a></li>
<small class="text-muted">scenario setting list</small>
{% for sc in scenarios[1] %}
<li><a href="{{ url_for('CONFIG_APP.scenario', scenario_name='user_defined_'+sc) }}">{{sc}}</a></li>
<li><a href="{{ url_for('CONFIG_APP.scenario', scenario_name=sc) }}">{{sc}}</a></li>
{% endfor %}
{% else %}
<text class="form-control" id="err_msg" data-toggle="tooltip"
@@ -46,13 +144,13 @@
class="caret"></span></a>
<ul class="dropdown-menu">
{% if launches[0] %}
<small class="text-muted">default</small>
{% for lc in launches[0] %}
<li><a href="{{ url_for('CONFIG_APP.launch', launch_name=lc) }}">{{lc}}</a></li>
{% endfor %}
<small class="text-muted">user-defined</small>
<li><a href="" data-toggle="modal" data-target="#create_modal" class="create_menu"
data-id="launch">Create a new Launch script</a></li>
<li><a href="" data-toggle="modal" data-target="#load_launch_modal" class="load_menu"
data-id="launch">Load a default launch script</a></li>
<small class="text-muted">launch setting list</small>
{% for lc in launches[1] %}
<li><a href="{{ url_for('CONFIG_APP.launch', launch_name='user_defined_'+lc) }}">{{lc}}</a></li>
<li><a href="{{ url_for('CONFIG_APP.launch', launch_name=lc) }}">{{lc}}</a></li>
{% endfor %}
{% else %}
<text class="form-control" id="err_msg" data-toggle="tooltip"
@@ -64,13 +162,13 @@
</ul>
</div>
</nav>
<form action="" enctype="multipart/form-data" method='POST'>
<form class="form-horizontal" action="" enctype="multipart/form-data" method='POST'>
<div class="form-group">
<label for="board_info" class="col-sm-1 control-label" style="text-align: left;">Board info:</label>
<div class="col-sm-3">
<label class="col-sm-1 control-label" style="text-align: left;">&nbsp;&nbsp;Board info:</label>
<div class="col-sm-2">
<div class="dropdown">
<select class="selectpicker" id="board_info">
<option style="display:none">
<option disabled selected value> -- Select an option -- </option>
{% for bi in board_info_list %}
{% if bi==board_info %}
<option value="{{bi}}" selected="selected">{{bi}}</option>
@@ -81,7 +179,8 @@
</select>
</div>
</div>
<text class="col-sm-2" id="board_type">{{board_type if board_type != None else ''}}</text>
<label class="col-sm-1 control-label">&nbsp;&nbsp;Board type:</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'>
<label for="board_info_file" class="custom-file-upload btn btn-primary" id="board_info_file2"
@@ -93,6 +192,12 @@
</form>
</div>
</div>
<div class="form-group">
<label class="col-sm-1"></label>
<text class="col-sm-2 control-label" id="bios_info" style="white-space: pre-line">{{bios_info if bios_info != None else ''}}</text>
<label class="col-sm-1"></label>
<text class="col-sm-2" id="base_board_info" style="white-space: pre-line">{{base_board_info if base_board_info != None else ''}}</text>
</div>
</form>
<hr class="col-sm-12">

View File

@@ -10,18 +10,62 @@
<h4 class="modal-title" id="myModalLabel">Save as</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="new_launch_name" class="col-sm-3 control-label">Launch: </label>
<div class="form-group row">
<label for="new_launch_name" class="col-sm-3 control-label">Launch Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="new_launch_name"
value={{launch[13:] if launch.startswith('user_defined_') else launch}}>
value={{launch}}>
</div>
</div>
<div class="form-group row hidden" id="src_path_row">
<label for="src_path" class="col-sm-3 control-label"
title="the relative path of acrn-hypervisor; if no path is specified,
the launch scripts will be generated into misc/acrn-config/xmls/config-xmls/[board]/output and overwirte the previous files.">
Source Path: </label>
<div class="col-sm-9">
<input type="text" class="form-control" id="src_path" value=""
placeholder="input the path to generate launch scripts">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="remove_launch" class="btn btn-default" data-dismiss="modal">Remove</button>
<button type="button" id="save_launch" data-id="" class="btn btn-primary" data-dismiss="modal">Submit
<button type="button" id="save_launch" data-id="" class="btn btn-primary">Submit
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="add_launch_modal" tabindex="-1" role="dialog" aria-labelledby="addlaunchModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="addlaunchModalLabel">Add a new VM</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="add_launch_type" class="col-sm-3 control-label">VM type: </label>
<div class="dropdown col-sm-6">
<select class="selectpicker" data-width="auto" id="add_launch_type">
<option value="LAUNCH_STANDARD_VM">LAUNCH_STANDARD_VM</option>
<option value="LAUNCH_RTVM">LAUNCH_RTVM</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="new_launch_name2" class="col-sm-3 control-label">Launch Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="new_launch_name2"
value={{ launch }}>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="add_launch_submit" data-id="" class="btn btn-primary" data-dismiss="modal">Submit
</button>
</div>
</div>
@@ -40,20 +84,20 @@
<label for="launch_file" class="btn btn-primary" id="scenario_file2"
style="border: 1px solid #ccc; display: inline-block; padding: 6px 12px;
cursor: pointer; border-radius:5px; ">
Import</label>
Import XML</label>
<input type="file" name="file" id="launch_file" class="col-sm-1 btn btn-primary" style="display: none;">
{% else %}
<label class="btn"
style="border: 1px solid #ccc; display: inline-block; padding: 6px 12px;
cursor: pointer; border-radius:5px; ">
Import</label>
Import XML</label>
<input type="file" name="file" class="col-sm-1" style="display: none;" disabled>
{% endif %}
</div>
{% if board_info != None and root != None %}
<div class="col-sm-1">
<button type="button" class="btn btn-primary" data-id="save" data-toggle="modal" data-target="#save_modal">
Export
<button type="button" class="btn btn-primary" data-id="save" data-toggle="modal" data-target="#save_modal"
id="export_launch_xml">Export XML
</button>
</div>
<div class="col-sm-1">
@@ -63,7 +107,7 @@
</div>
{% else %}
<div class="col-sm-1">
<button type="button" disabled class="btn btn-primary">Export</button>
<button type="button" disabled class="btn btn-primary">Export XML</button>
</div>
<div class="col-sm-1">
<button type="button" disabled class="btn btn-primary">Generate Launch Script</button>
@@ -76,20 +120,14 @@
<div class="dropdown col-sm-9">
<select class="selectpicker" data-width="auto" id="scenario_name">
<option style="display:none">
{% for sc in scenarios[0] %}
{% if root != None and root.attrib['scenario'] == sc %}
<option disabled selected value> -- Select an option -- </option>
{% for sc in scenarios[1] %}
{% if root !=None and root.attrib['scenario'] == sc%}
<option value="{{sc}}" selected>{{sc}}</option>
{% else %}
<option value="{{sc}}">{{sc}}</option>
{% endif %}
{% endfor %}
{% for sc in scenarios[1] %}
{% if root !=None and root.attrib['scenario'] == 'user_defined_'+sc%}
<option value="{{'user_defined_'+sc}}" selected>{{'user_defined_'+sc}}</option>
{% else %}
<option value="{{'user_defined_'+sc}}">{{'user_defined_'+sc}}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
@@ -103,6 +141,14 @@
<label class="col-sm-2 control-label">UOS: </label>
<label class="col-sm-1 control-label" id="vm">{{vm.attrib['id']}}</label>
</div>
<div class="form-group">
<button type="button" class="btn" id="add_launch_vm" data-id="{{vm.attrib['id']}}" data-toggle="modal"
data-target="#add_launch_modal">Add a VM below</button>
</div>
<div class="form-group">
<button type="button" class="btn" id="remove_launch_vm" data-id="{{vm.attrib['id']}}">
Remove this VM</button>
</div>
</td>
<td>
{% for elem in vm.getchildren() %}
@@ -142,6 +188,7 @@
<select class="selectpicker" data-width="auto" title=""
id="{{'uos:id='+vm.attrib['id']+','+elem.tag}}">
{% endif %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in launch_item_values[','.join(['uos', elem.tag])] %}
{% if item_value == elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
@@ -164,7 +211,6 @@
<div class="form-group">
{% if 'id' not in elem.attrib %}
{% if not first_child %}
{% do first_child.append(1) %}
<label class="col-sm-1 control-label" data-toggle="tooltip"
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
{{elem.tag}}</label>
@@ -178,7 +224,8 @@
title="{{sub_elem.attrib['desc'] if 'desc' in sub_elem.attrib else sub_elem.tag}}">
{{sub_elem.tag}}</label>
{% if ','.join(['uos', elem.tag, sub_elem.tag]) not in launch_item_values %}
{% if ','.join(['uos', elem.tag, sub_elem.tag]) not in launch_item_values
and elem.tag != 'vcpu_affinity'%}
<div class="col-sm-5">
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
<input type="text" class="form-control" readonly
@@ -204,6 +251,8 @@
{% endif%}
{% else %}
{% set item_key = ','.join(['uos', elem.tag, sub_elem.tag]) if elem.tag != 'vcpu_affinity'
else ','.join(['uos', elem.tag]) %}
<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
@@ -212,7 +261,8 @@
<select class="selectpicker" data-width="auto"
id="{{'uos:id='+vm.attrib['id']+','+elem.tag+','+sub_elem.tag}}">
{% endif %}
{% for item_value in launch_item_values[','.join(['uos', elem.tag, sub_elem.tag])] %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in launch_item_values[item_key] %}
{% if item_value == sub_elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
{% else %}
@@ -220,8 +270,17 @@
{% endif %}
{% endfor %}
</select>
{% if elem.tag == 'vcpu_affinity' %}
<button type="button" class="btn" id="add_vcpu_{{first_child|length}}">+</button>
{% if not first_child %}
<button type="button" disabled class="btn" id="remove_vcpu_{{first_child|length}}">-</button>
{% else %}
<button type="button" class="btn" id="remove_vcpu_{{first_child|length}}">-</button>
{% endif %}
{% endif %}
</div>
{% endif %}
{% do first_child.append(1) %}
<p id="{{'uos:id='+vm.attrib['id']+','+elem.tag+','+sub_elem.tag}}_err" class="col-sm-3"></p>
{% else %}
{% if not first_child %}
@@ -260,6 +319,7 @@
<select class="selectpicker" data-width="auto"
id="{{'uos:id='+vm.attrib['id']+','+elem.tag+':id='+elem.attrib['id']+','+sub_elem.tag}}">
{% endif %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in launch_item_values[','.join(['uos', elem.tag, sub_elem.tag])] %}
{% if item_value == sub_elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
@@ -318,6 +378,10 @@
</td>
</tr>
{% endfor %}
<tr><td>
<button type="button" class="btn" id="add_launch_script" data-toggle="modal" data-id="-1"
data-target="#add_launch_modal">Add a New VM</button>
</td></tr>
</table>
{% else %}
<text class="form-control" id="err_msg">No setting available. Select one board info and make sure the launch xml

View File

@@ -10,18 +10,66 @@
<h4 class="modal-title" id="myModalLabel">Save as</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label for="new_scenario_name" class="col-sm-3 control-label">Scenario: </label>
<div class="form-group row">
<label for="new_scenario_name" class="col-sm-3 control-label">Scenario Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="new_scenario_name"
value={{ scenario[13:] if scenario.startswith('user_defined_') else scenario }}>
value={{ scenario }}>
</div>
</div>
<div class="form-group row hidden" id="src_path_row">
<label for="src_path" class="col-sm-3 control-label"
title="the relative path of acrn-hypervisor; if no path is specified,
the source files will be generated into default path and overwirte the previous files.">
Source Path: </label>
<div class="col-sm-9">
<input type="text" class="form-control" id="src_path" value=""
placeholder="input the path to generate source files">
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="remove_scenario" class="btn btn-default" data-dismiss="modal">Remove</button>
<button type="button" id="save_scenario" data-id="" class="btn btn-primary" data-dismiss="modal">Submit
<button type="button" id="save_scenario" data-id="" class="btn btn-primary">Submit
</button>
</div>
</div>
</div>
</div>
<div class="modal fade" id="add_vm_modal" tabindex="-1" role="dialog" aria-labelledby="addVMModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="addVMModalLabel">Add a new VM</h4>
</div>
<div class="modal-body">
<div class="form-group row">
<label for="add_vm_type" class="col-sm-3 control-label">VM type: </label>
<div class="dropdown col-sm-6">
<select class="selectpicker" data-width="auto" id="add_vm_type">
<option value="PRE_STD_VM">PRE_STD_VM</option>
<option value="SAFETY_VM">SAFETY_VM</option>
<option value="SOS_VM">SOS_VM</option>
<option value="POST_STD_VM">POST_STD_VM</option>
<option value="POST_RT_VM">POST_RT_VM</option>
<option value="KATA_VM">KATA_VM</option>
</select>
</div>
</div>
<div class="form-group row">
<label for="new_scenario_name2" class="col-sm-3 control-label">Scenario Name: </label>
<div class="col-sm-6">
<input type="text" class="form-control" id="new_scenario_name2"
value={{ scenario }}>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>
<button type="button" id="add_vm_submit" data-id="" class="btn btn-primary" data-dismiss="modal">Submit
</button>
</div>
</div>
@@ -40,20 +88,20 @@
<label for="scenario_file" class="btn btn-primary" id="scenario_file2"
style="border: 1px solid #ccc; display: inline-block; padding: 6px 12px;
cursor: pointer; border-radius:5px; ">
Import</label>
Import XML</label>
<input type="file" name="file" id="scenario_file" class="col-sm-1 btn btn-primary" style="display: none;">
{% else %}
<label for="scenario_file" class="btn"
style="border: 1px solid #ccc; display: inline-block; padding: 6px 12px;
cursor: pointer; border-radius:5px; ">
Import</label>
Import XML</label>
<input type="file" name="file" class="col-sm-1" style="display: none;" disabled>
{% endif %}
</div>
{% if board_info != None and root != None and scenario_item_values %}
<div class="col-sm-1">
<button type="button" data-id="save" class="btn btn-primary" data-toggle="modal" data-target="#save_modal">
Export
<button type="button" data-id="" class="btn btn-primary" data-toggle="modal" data-target="#save_modal"
id="export_scenario_xml">Export XML
</button>
</div>
<div class="col-sm-2">
@@ -63,8 +111,7 @@
</div>
{% else %}
<div class="col-sm-1">
<button type="button" disabled class="btn btn-primary" data-toggle="modal" data-target="#save_modal">
Export
<button type="button" disabled class="btn btn-primary" data-toggle="modal" data-target="#save_modal">Export XML
</button>
</div>
<div class="col-sm-2">
@@ -90,12 +137,23 @@
<div class="form-group">
<label class="col-sm-1 control-label">HV </label>
</div>
<div class="form-group">
<button type="button" class="btn" id="add_vm" data-id="-1" data-toggle="modal"
data-target="#add_vm_modal">Add a VM below</button>
</div>
{% else %}
{% set vm_type = 'vm:id='+vm.attrib['id'] %}
<div class="form-group">
<label class="col-sm-1 control-label">VM: </label>
<label class="col-sm-1 control-label" id="vm">{{vm.attrib['id']}}</label>
</div>
<div class="form-group">
<button type="button" class="btn" id="add_vm" data-id="{{vm.attrib['id']}}" data-toggle="modal"
data-target="#add_vm_modal">Add a VM below</button>
</div>
<div class="form-group">
<button type="button" class="btn" id="remove_vm" data-id="{{vm.attrib['id']}}">
Remove this VM</button>
</div>
{% endif %}
{% if 'desc' in vm.attrib or vm.attrib['desc'] == 'specific for Kata' %}
@@ -133,6 +191,7 @@
<select class="selectpicker" data-width="auto"
id="{{vm_type+','+elem.tag}}">
{% endif %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in scenario_item_values[','.join([vm.tag, elem.tag])] %}
{% if item_value == elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
@@ -167,7 +226,8 @@
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 != 'vcpu_affinity' %}
{% if ','.join([vm.tag, elem.tag, sub_elem.tag]) not in scenario_item_values
and elem.tag != 'vcpu_affinity' and elem.tag != 'pci_devs' %}
{% if sub_elem.tag in ['bootargs', 'kern_args'] %}
<div class="col-sm-6">
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
@@ -193,8 +253,8 @@
</div>
{% endif %}
{% else %}
{% set item_key = ','.join([vm.tag, elem.tag, sub_elem.tag]) if elem.tag != 'vcpu_affinity' else
','.join([vm.tag, elem.tag])%}
{% set item_key = ','.join([vm.tag, elem.tag, sub_elem.tag]) if elem.tag != 'vcpu_affinity'
and elem.tag != 'pci_devs' else ','.join([vm.tag, elem.tag]) %}
<div class="dropdown col-sm-6">
{% if 'readonly' in sub_elem.attrib and sub_elem.attrib['readonly'] == 'true' %}
<select class="selectpicker" data-width="auto"
@@ -203,6 +263,7 @@
<select class="selectpicker" data-width="auto"
id="{{vm_type+','+elem.tag+','+sub_elem.tag}}">
{% endif %}
<option disabled selected value> -- Select an option -- </option>
{% for item_value in scenario_item_values[item_key] %}
{% if item_value == sub_elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>
@@ -219,6 +280,14 @@
{% else %}
<button type="button" class="btn" id="remove_vcpu_{{first_child|length}}">-</button>
{% endif %}
{% elif elem.tag == 'pci_devs' %}
<button type="button" class="btn" id="add_pci_dev_{{first_child|length}}">+</button>
{% if not first_child %}
<button type="button" disabled class="btn" id="remove_pci_dev_{{first_child|length}}">-</button>
{% else %}
<button type="button" class="btn" id="remove_pci_dev_{{first_child|length}}">-</button>
{% endif %}
{% else %}
{% endif%}
</div>
{% endif %}
@@ -268,6 +337,7 @@
{% set key = ('vm='+vm.attrib['id']+','+elem.tag+'='+elem.attrib['id']+','+sub_elem.tag)
if (elem.tag=='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] %}
{% if item_value == sub_elem_text %}
<option value="{{item_value}}" selected="selected">{{item_value}}</option>