misc: Configurator Main VM Support

This patch is to support Main VM, i.e., the Main VM scenario is similar to
paritioned scenario, which select one VM as Main VM and owns the
physical resources.

I extracted all pcis from the board, substracted them with dispatched ones
and then make an assignment to replace the old enums.

This is implemented through two methods called updateSchema which is
to update schema on the current VM and updateLoadSchema which is
to maintain pcis, i.e. removed the pcis listed on the pre-launched VM,
while loading scenario.xml.

I tested locally and confirmed the functionalties above are implemented.

Signed-off-by: dongpingx <dongpingx.wu@intel.com>
Tracked-On: #8657
This commit is contained in:
dongpingx 2024-07-17 14:37:36 +08:00 committed by acrnsi-robot
parent 03c2a199e9
commit 56108c0a1f
4 changed files with 101 additions and 2 deletions

View File

@ -651,6 +651,10 @@ class PythonObject {
generateConfigSummary(boardXMLText, scenarioXMLText) { generateConfigSummary(boardXMLText, scenarioXMLText) {
return this.api('generateConfigSummary', 'plaintext', boardXMLText, scenarioXMLText) return this.api('generateConfigSummary', 'plaintext', boardXMLText, scenarioXMLText)
} }
updateSchema(boardXMLText, scenarioXMLText) {
return this.api('updateSchema', 'plaintext', boardXMLText, scenarioXMLText)
}
} }
class Configurator { class Configurator {

View File

@ -140,6 +140,8 @@ export default {
errors: [], errors: [],
totalMsg: "", totalMsg: "",
showTotalMessageFlag: false, showTotalMessageFlag: false,
isSaved:false,
isLoaded:false
} }
}, },
computed: { computed: {
@ -151,6 +153,18 @@ export default {
} }
}, },
methods: { methods: {
updateSchema(i){
let current_selected_pcis=this.scenario.vm[i]['pci_devs']['pci_dev']
let total_pcis=this.schemas.PreLaunchedVM.BasicConfigType.definitions.PCIDevsConfiguration.properties.pci_dev.items
console.log('before:',total_pcis.enum.length)
let s=new Set(total_pcis.enum)
current_selected_pcis.map(e=>{
s.delete(e)
})
let to_updated=Array.from(s).sort()
total_pcis.enum=total_pcis.enumNames=to_updated
console.log('after:',total_pcis.enum.length)
},
back() { back() {
this.$router.back() this.$router.back()
}, },
@ -175,10 +189,28 @@ export default {
this.updateCurrentBoardInfo() this.updateCurrentBoardInfo()
this.switchTab(-1) this.switchTab(-1)
}, },
updateLoadSchema(){
let total=[]
this.scenario.vm.map((vmConfig)=>{
if(vmConfig.pci_devs!==undefined){//at least typeof pci_devs=='object', i.e.,{}
total.push(...vmConfig.pci_devs.pci_dev)
}
})
let current=configurator.pythonObject.updateSchema(this.board.content,total)
let retSch=JSON.parse(current)
this.schemas.PreLaunchedVM.BasicConfigType.definitions.PCIDevsConfiguration.properties.pci_dev.items.enum=this.schemas.PreLaunchedVM.BasicConfigType.definitions.PCIDevsConfiguration.properties.pci_dev.items.enumNames=retSch
},
updateCurrentFormSchema() { updateCurrentFormSchema() {
if (this.activeVMID === -1) { if (this.activeVMID === -1) {
this.currentFormSchema = this.schemas.HV this.currentFormSchema = this.schemas.HV
} else { } else {
if(!this.isLoaded){
this.updateLoadSchema()
this.isLoaded=true
}
if(this.isSaved){
this.updateLoadSchema()
}
this.scenario.vm.map((vmConfig) => { this.scenario.vm.map((vmConfig) => {
if (vmConfig['@id'] === this.activeVMID) { if (vmConfig['@id'] === this.activeVMID) {
let vm_schema = { let vm_schema = {
@ -221,6 +253,9 @@ export default {
for (let i = 0; i < this.scenario.vm.length; i++) { for (let i = 0; i < this.scenario.vm.length; i++) {
if (this.scenario.vm[i]['@id'] === this.activeVMID) { if (this.scenario.vm[i]['@id'] === this.activeVMID) {
this.currentFormData = this.scenario.vm[i] this.currentFormData = this.scenario.vm[i]
if(this.scenario.vm[i]['load_order']=='PRE_LAUNCHED_VM'&&this.isSaved){
this.updateSchema(i)
}
} }
} }
}, },
@ -490,7 +525,10 @@ export default {
configurator.writeFile(this.WorkingFolder + 'scenario.xml', scenarioXMLData) configurator.writeFile(this.WorkingFolder + 'scenario.xml', scenarioXMLData)
.then(() => { .then(() => {
this.isSaved=true
this.updateCurrentFormData() this.updateCurrentFormData()
this.isSaved=false
this.isLoaded=false
}) })
.then(() => { .then(() => {
// validate scenario and clean up the launch script // validate scenario and clean up the launch script

View File

@ -32,7 +32,7 @@
</b-form-radio> </b-form-radio>
<b-form-radio class="mb-3" v-model="scenarioTemplate" value="partitioned"> <b-form-radio class="mb-3" v-model="scenarioTemplate" value="partitioned">
Partitioned <i>(Pre-launched VMs only)</i> Partitioned <i>(Pre-launched VMs or with Main VM)</i>
</b-form-radio> </b-form-radio>
<b-form-radio class="mb-3" v-model="scenarioTemplate" value="hybrid"> <b-form-radio class="mb-3" v-model="scenarioTemplate" value="hybrid">
@ -53,6 +53,10 @@
<b-form-input v-if="scenarioTemplate!=='shared'" type="number" min="0" max="8" v-model="preLaunch"/> <b-form-input v-if="scenarioTemplate!=='shared'" type="number" min="0" max="8" v-model="preLaunch"/>
<b v-if="scenarioTemplate!=='partitioned'">Service VM:</b> <b v-if="scenarioTemplate!=='partitioned'">Service VM:</b>
<b-form-input v-if="scenarioTemplate!=='partitioned'" disabled type="number" model-value="1"/> <b-form-input v-if="scenarioTemplate!=='partitioned'" disabled type="number" model-value="1"/>
<b v-if="scenarioTemplate=='partitioned'">Main VM:</b>
<b-form-input v-if="scenarioTemplate=='partitioned'" min="0" max="1" type="number" v-model="mainVM"/>
<b v-if="scenarioTemplate!=='partitioned'">Post-launch VMs:</b> <b v-if="scenarioTemplate!=='partitioned'">Post-launch VMs:</b>
<b-form-input v-if="scenarioTemplate!=='partitioned'" type="number" min="0" max="8" v-model="postLaunch"/> <b-form-input v-if="scenarioTemplate!=='partitioned'" type="number" min="0" max="8" v-model="postLaunch"/>
</div> </div>
@ -83,7 +87,8 @@ export default {
version: branchVersion, version: branchVersion,
scenarioTemplate: "shared", scenarioTemplate: "shared",
preLaunch: 1, preLaunch: 1,
postLaunch: 1 postLaunch: 1,
mainVM: 1
} }
}, },
methods: { methods: {
@ -102,6 +107,7 @@ export default {
post = this.postLaunch post = this.postLaunch
} else if (this.scenarioTemplate === 'partitioned') { } else if (this.scenarioTemplate === 'partitioned') {
pre = this.preLaunch pre = this.preLaunch
service = this.mainVM;
} else if (this.scenarioTemplate === 'hybrid') { } else if (this.scenarioTemplate === 'hybrid') {
pre = this.preLaunch; pre = this.preLaunch;
service = 1; service = 1;

View File

@ -0,0 +1,51 @@
#!/usr/bin/env python3
__package__ = 'configurator.pyodide'
from .pyodide import convert_result, nuc11_board, nuc11_scenario
import re
from lxml import etree
class GenerateSchema:
def __init__(self, board, scenario):
parser = etree.XMLParser(remove_blank_text=True)
self.board_etree = etree.fromstring(board, parser)
self.scenario = scenario
@property
def pcis(self):
line = self.board_etree.xpath('/acrn-config/PCI_DEVICE/text()')[0]
cnt = []
for line in line.replace('\t', '').split('\n'):
re_cpi = re.compile(r'^([0-9A-Fa-f]{1,2}:[0-1][0-9A-Fa-f]\.[0-7].*)\(')
ret_ = re_cpi.search(line)
if ret_:
ret = ret_.group(1).strip()
if re.search(r'^00:00.0', ret): # omit 00:00.0
continue
cnt.append(ret)
return cnt
@property
def schemas(self):
return self.scenario
def update(self):
return sorted(list(set(self.pcis) - set(self.schemas)))
def updateSchema(board, scenario):
return convert_result(GenerateSchema(board, scenario).update())
main = updateSchema
def test():
main(nuc11_board, nuc11_scenario)
if __name__ == '__main__':
test()