Skip to content

Commit 83ee8ce

Browse files
authored
Merge pull request #653 from jeongda-young/pciHostdevices
devices 태그, 가상머신이 정지 된 후 호스트 디바이스 탭 안보이는 오류 수정
2 parents 424235f + c409cc8 commit 83ee8ce

2 files changed

Lines changed: 111 additions & 9 deletions

File tree

ui/src/views/compute/InstanceTab.vue

Lines changed: 108 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
:virtualmachine="vm"
116116
:loading="loading"/>
117117
</a-tab-pane>
118-
<a-tab-pane :tab="$t('label.listhostdevices')" key="pcidevices" v-if="hasPciDevices">
118+
<a-tab-pane :tab="$t('label.listhostdevices')" key="pcidevices" v-if="shouldShowPciDevicesTab">
119119
<div v-if="pciDevices.length > 0">
120120
<a-table
121121
:columns="pciColumns"
@@ -318,6 +318,12 @@ export default {
318318
},
319319
mounted () {
320320
this.setCurrentTab()
321+
this.fetchPciDevices()
322+
},
323+
computed: {
324+
shouldShowPciDevicesTab () {
325+
return this.pciDevices.length > 0
326+
}
321327
},
322328
methods: {
323329
setCurrentTab () {
@@ -353,11 +359,10 @@ export default {
353359
}
354360
})
355361
356-
// PCI 디바이스 할당 여부만 확인
357362
this.hasPciDevices = false
358363
if (this.vm.details) {
359364
for (const [key, value] of Object.entries(this.vm.details)) {
360-
if (key.startsWith('extraconfig-') && value.includes('<hostdev')) {
365+
if (key.startsWith('extraconfig-') && (value.includes('<hostdev') || value.includes('pci'))) {
361366
this.hasPciDevices = true
362367
break
363368
}
@@ -418,14 +423,113 @@ export default {
418423
async handleChangeTab (activeKey) {
419424
if (activeKey === 'pcidevices') {
420425
await this.fetchPciDevices()
426+
if (this.pciDevices.length === 0) {
427+
this.currentTab = 'details'
428+
return
429+
}
421430
}
422431
if (this.currentTab !== activeKey) {
423432
this.currentTab = activeKey
424433
}
425434
},
426435
async fetchPciDevices () {
427436
this.pciDevices = []
428-
if (!this.vm.hostid) return
437+
if (!this.vm.hostid) {
438+
// VM이 정지된 상태에서도 PCI 디바이스 정보 표시
439+
if (this.vm.details) {
440+
const pciAddresses = []
441+
442+
for (const [key, value] of Object.entries(this.vm.details)) {
443+
if (key.startsWith('extraconfig-') && value.includes('<hostdev')) {
444+
const sourceMatch = value.match(/<source>\s*<address[^>]*domain='([^']*)'[^>]*bus='([^']*)'[^>]*slot='([^']*)'[^>]*function='([^']*)'[^>]*\/>\s*<\/source>/)
445+
if (sourceMatch) {
446+
const [, domain, bus, slot, function_] = sourceMatch
447+
448+
const domainHex = domain.replace('0x', '')
449+
const busHex = bus.replace('0x', '')
450+
const slotHex = slot.replace('0x', '')
451+
const functionHex = function_.replace('0x', '')
452+
const pciAddress = `${busHex.padStart(2, '0')}:${slotHex.padStart(2, '0')}.${functionHex}`
453+
pciAddresses.push({
454+
key: key,
455+
pciAddress: pciAddress,
456+
domain: domainHex,
457+
bus: busHex,
458+
slot: slotHex,
459+
function: functionHex
460+
})
461+
} else {
462+
}
463+
}
464+
}
465+
if (pciAddresses.length > 0) {
466+
try {
467+
let hostId = this.vm.hostid || this.vm.lastHostId
468+
if (!hostId) {
469+
const zoneResponse = await api('listHosts', {
470+
zoneid: this.vm.zoneid,
471+
type: 'Routing',
472+
state: 'Up'
473+
})
474+
475+
if (zoneResponse?.listhostsresponse?.host && zoneResponse.listhostsresponse.host.length > 0) {
476+
hostId = zoneResponse.listhostsresponse.host[0].id
477+
}
478+
}
479+
480+
if (!hostId) {
481+
console.error('No hostId available for PCI device lookup')
482+
pciAddresses.forEach(addr => {
483+
this.pciDevices.push({
484+
key: addr.key,
485+
hostDevicesName: `PCI Device at ${addr.pciAddress}`,
486+
hostDevicesText: `Domain: ${addr.domain}, Bus: ${addr.bus}, Slot: ${addr.slot}, Function: ${addr.function}`
487+
})
488+
})
489+
return
490+
}
491+
492+
const response = await api('listHostDevices', {
493+
id: hostId
494+
})
495+
496+
const devices = response?.listhostdevicesresponse?.listhostdevices?.[0]
497+
if (devices && devices.hostdevicesname && devices.hostdevicestext) {
498+
for (let i = 0; i < devices.hostdevicesname.length; i++) {
499+
const deviceName = devices.hostdevicesname[i]
500+
const deviceText = devices.hostdevicestext[i]
501+
const pciMatch = deviceName.match(/^([0-9a-fA-F]{2}:[0-9a-fA-F]{2}\.[0-9a-fA-F])/)
502+
if (pciMatch) {
503+
const devicePciAddress = pciMatch[1].toLowerCase()
504+
505+
const matchingAddress = pciAddresses.find(addr => {
506+
const addrLower = addr.pciAddress.toLowerCase()
507+
return addrLower === devicePciAddress
508+
})
509+
if (matchingAddress) {
510+
console.log('Found matching device:', deviceName)
511+
this.pciDevices.push({
512+
key: matchingAddress.key,
513+
hostDevicesName: deviceName,
514+
hostDevicesText: deviceText
515+
})
516+
}
517+
}
518+
}
519+
}
520+
} catch (error) {
521+
pciAddresses.forEach(addr => {
522+
this.pciDevices.push({
523+
key: addr.key,
524+
hostDevicesName: `PCI Device at ${addr.pciAddress}`,
525+
hostDevicesText: `Domain: ${addr.domain}, Bus: ${addr.bus}, Slot: ${addr.slot}, Function: ${addr.function}`
526+
})
527+
})
528+
}
529+
}
530+
}
531+
return
532+
}
429533
430534
try {
431535
const vmNumericId = this.vm.instancename.split('-')[2]

ui/src/views/storage/HostDevicesTransfer.vue

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,9 @@ export default {
250250
251251
const vm = response?.listvirtualmachinesresponse?.virtualmachine?.[0]
252252
const details = vm?.details || {}
253-
254-
// extraconfig에 해당 호스트 디바이스 설정이 남아있는지 확인
255253
const hasDeviceConfig = Object.values(details).some(value =>
256254
value.includes('<hostdev') && value.includes(hostDevicesName)
257255
)
258-
259-
// 설정이 남아있다면 삭제하지 않음
260256
if (hasDeviceConfig) {
261257
return
262258
}
@@ -277,17 +273,18 @@ export default {
277273
},
278274
279275
generateXmlConfig (hostDeviceName) {
280-
// PCI 디바이스인 경우 (기존 로직)
281276
const [pciAddress] = hostDeviceName.split(' ')
282277
const [bus, slotFunction] = pciAddress.split(':')
283278
const [slot, func] = slotFunction.split('.')
284279
285280
return `
281+
<devices>
286282
<hostdev mode='subsystem' type='pci' managed='yes'>
287283
<source>
288284
<address domain='0x0000' bus='0x${bus}' slot='0x${slot}' function='0x${func}'/>
289285
</source>
290286
</hostdev>
287+
</devices>
291288
`.trim()
292289
},
293290
@@ -321,3 +318,4 @@ export default {
321318
}
322319
}
323320
</style>
321+

0 commit comments

Comments
 (0)