Skip to content

Commit 20c1270

Browse files
jeongda-youngDajeong-Park
authored andcommitted
디바이스 ui, api
1 parent c8a4bab commit 20c1270

File tree

10 files changed

+3722
-7009
lines changed

10 files changed

+3722
-7009
lines changed

core/src/main/java/com/cloud/resource/ServerResourceBase.java

Lines changed: 895 additions & 219 deletions
Large diffs are not rendered by default.

server/src/main/java/com/cloud/server/ManagementServerImpl.java

Lines changed: 584 additions & 2053 deletions
Large diffs are not rendered by default.

ui/public/locales/en.json

Lines changed: 384 additions & 866 deletions
Large diffs are not rendered by default.

ui/public/locales/ko_KR.json

Lines changed: 523 additions & 636 deletions
Large diffs are not rendered by default.

ui/src/views/compute/InstanceTab.vue

Lines changed: 580 additions & 435 deletions
Large diffs are not rendered by default.

ui/src/views/infra/ListHostDevicesTab.vue

Lines changed: 493 additions & 1622 deletions
Large diffs are not rendered by default.

ui/src/views/storage/HostHbaDevicesTransfer.vue

Lines changed: 50 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,6 @@ import { api } from '@/api'
6262
6363
export default {
6464
name: 'HostHbaDevicesTransfer',
65-
i18n: {
66-
messages: {
67-
ko: {
68-
'message.success.hba.device.allocated': 'HBA 디바이스가 성공적으로 할당되었습니다.'
69-
}
70-
}
71-
},
7265
props: {
7366
resource: {
7467
type: Object,
@@ -106,11 +99,11 @@ export default {
10699
api('listVirtualMachines', params)
107100
.then(vmResponse => {
108101
const vms = vmResponse.listvirtualmachinesresponse?.virtualmachine || []
109-
// console.log(`Fetched ${vms.length} Running VMs`)
102+
console.log(`Fetched ${vms.length} Running VMs`)
110103
111104
// 인스턴스 이름이 있는 VM만 필터링
112105
const validVms = vms.filter(vm => vm.instancename && vm.instancename.trim() !== '')
113-
// console.log(`Valid VMs with instance name: ${validVms.length}`)
106+
console.log(`Valid VMs with instance name: ${validVms.length}`)
114107
115108
return validVms.map(vm => ({
116109
...vm,
@@ -123,8 +116,8 @@ export default {
123116
}),
124117
// 현재 HBA 디바이스 할당 상태 가져오기
125118
api('listHostHbaDevices', { id: this.resource.id })
126-
]).then(async ([vms, hbaResponse]) => {
127-
// console.log('Total valid VMs fetched:', vms.length)
119+
]).then(([vms, hbaResponse]) => {
120+
console.log('Total valid VMs fetched:', vms.length)
128121
129122
// HBA 할당 상태 확인
130123
const hbaData = hbaResponse?.listhosthbadevicesresponse?.listhosthbadevices?.[0]
@@ -134,66 +127,34 @@ export default {
134127
const currentDeviceVmId = vmAllocations[this.resource.hostDevicesName]
135128
console.log('Current device VM ID:', currentDeviceVmId)
136129
137-
// 모든 HBA 디바이스가 할당된 VM들을 필터링하고, 존재하지 않는 VM은 자동으로 할당 해제
130+
// 모든 HBA 디바이스가 할당된 VM들을 필터링
138131
const allocatedVmIds = new Set()
139-
const processedDevices = new Set()
140-
141-
for (const [deviceName, vmId] of Object.entries(vmAllocations)) {
142-
if (vmId && !processedDevices.has(deviceName)) {
143-
try {
144-
// VM이 실제로 존재하는지 확인
145-
const vmResponse = await api('listVirtualMachines', { id: vmId, listall: true })
146-
const vm = vmResponse.listvirtualmachinesresponse?.virtualmachine?.[0]
147-
148-
if (vm && vm.state !== 'Expunging') {
149-
allocatedVmIds.add(vmId.toString())
150-
} else {
151-
// VM이 존재하지 않거나 Expunging 상태면 자동으로 할당 해제
152-
try {
153-
const xmlConfig = this.generateHbaDeallocationXmlConfig(deviceName)
154-
await api('updateHostHbaDevices', {
155-
hostid: this.resource.id,
156-
hostdevicesname: deviceName,
157-
virtualmachineid: null,
158-
xmlconfig: xmlConfig,
159-
isattach: false
160-
})
161-
// console.log(`Automatically deallocated HBA device ${deviceName} from deleted/expunging VM ${vmId}`)
162-
} catch (error) {
163-
console.error(`Failed to automatically deallocate HBA device ${deviceName}:`, error)
164-
}
165-
}
166-
} catch (error) {
167-
console.error(`Error checking VM ${vmId} for device ${deviceName}:`, error)
168-
// VM 조회 실패 시에도 할당 해제 시도
169-
try {
170-
const xmlConfig = this.generateHbaDeallocationXmlConfig(deviceName)
171-
await api('updateHostHbaDevices', {
172-
hostid: this.resource.id,
173-
hostdevicesname: deviceName,
174-
virtualmachineid: null,
175-
xmlconfig: xmlConfig,
176-
isattach: false
177-
})
178-
// console.log(`Automatically deallocated HBA device ${deviceName} after VM check error`)
179-
} catch (detachError) {
180-
console.error(`Failed to automatically deallocate HBA device ${deviceName} after error:`, detachError)
181-
}
182-
}
183-
processedDevices.add(deviceName)
132+
Object.values(vmAllocations).forEach(vmId => {
133+
if (vmId) {
134+
allocatedVmIds.add(vmId.toString())
184135
}
185-
}
136+
})
186137
187-
// console.log('All allocated VM IDs:', Array.from(allocatedVmIds))
138+
console.log('All allocated VM IDs:', Array.from(allocatedVmIds))
188139
189-
// HBA 디바이스는 같은 이름으로도 여러 할당이 가능하므로 모든 VM을 표시
190-
// 백엔드에서 같은 HBA 디바이스 이름으로도 여러 할당을 허용하므로 필터링하지 않음
191-
this.virtualmachines = vms
140+
// HBA 디바이스가 할당된 VM들을 제외 (인스턴스 번호로 비교)
141+
this.virtualmachines = vms.filter(vm => {
142+
// VM의 인스턴스 번호 추출 (i-2-163-VM -> 163)
143+
const instanceNumber = vm.instancename ? vm.instancename.split('-')[2] : null
144+
145+
// HBA 디바이스가 할당된 VM은 제외 (인스턴스 번호로 비교)
146+
if (instanceNumber && allocatedVmIds.has(instanceNumber)) {
147+
return false
148+
}
149+
return true
150+
})
192151
193152
if (this.virtualmachines.length === 0) {
194153
this.$notification.warning({
195154
message: this.$t('message.warning'),
196-
description: 'No VMs with valid instance names found. Please ensure VMs are properly running.'
155+
description: allocatedVmIds.size > 0
156+
? 'All VMs already have HBA devices allocated. Please deallocate an HBA device first to assign to another VM.'
157+
: 'No VMs with valid instance names found. Please ensure VMs are properly running.'
197158
})
198159
}
199160
}).catch(error => {
@@ -260,19 +221,22 @@ export default {
260221
bus = '0'
261222
target = '0'
262223
unit = '0'
263-
console.log('Constructed SCSI address from host number:', `${hostNum}:${bus}:${target}:${unit}`)
224+
console.log('Const ructed SCSI address from host number:', `${hostNum}:${bus}:${target}:${unit}`)
264225
}
265226
}
266227
228+
// 물리 HBA와 가상 HBA의 XML 구조를 다르게 처리
267229
if (this.resource && this.resource.deviceType === 'physical') {
268-
return `<hostdev mode='subsystem' type='scsi'>
230+
// 물리 HBA의 경우 더 간단한 XML 구조 사용
231+
return `<hostdev mode='subsystem' type='scsi' rawio='yes'>
269232
<source>
270233
<adapter name='${adapterName}'/>
271234
<address bus='${bus}' target='${target}' unit='${unit}'/>
272235
</source>
273236
</hostdev>`
274237
} else {
275-
return `<hostdev mode='subsystem' type='scsi'>
238+
// 가상 HBA의 경우 기존 XML 구조 사용
239+
return `<hostdev mode='subsystem' type='scsi' rawio='yes'>
276240
<source>
277241
<adapter name='${adapterName}'/>
278242
<address bus='${bus}' target='${target}' unit='${unit}'/>
@@ -281,50 +245,9 @@ export default {
281245
}
282246
},
283247
284-
// HBA 할당 해제용 XML 설정 생성
285-
generateHbaDeallocationXmlConfig (hostDeviceName) {
286-
// 할당 시와 동일한 SCSI 주소 생성 로직 사용
287-
let bus = '0'
288-
let target = '0'
289-
let unit = '0'
290-
let adapterName = hostDeviceName
291-
292-
// 디바이스 텍스트에서 SCSI 주소 추출 시도
293-
let scsiAddress = null
294-
if (this.resource.hostDevicesText) {
295-
scsiAddress = this.extractScsiAddress(this.resource.hostDevicesText)
296-
}
297-
298-
// 전달받은 SCSI 주소 사용
299-
if (scsiAddress) {
300-
const scsiParts = scsiAddress.split(':')
301-
if (scsiParts.length >= 4) {
302-
const hostNum = scsiParts[0]
303-
bus = scsiParts[1] || '0'
304-
target = scsiParts[2] || '0'
305-
unit = scsiParts[3] || '0'
306-
adapterName = `scsi_host${hostNum}`
307-
}
308-
} else {
309-
const scsiMatch = hostDeviceName.match(/scsi_host(\d+)/i)
310-
if (scsiMatch) {
311-
bus = '0'
312-
target = '0'
313-
unit = '0'
314-
}
315-
}
316-
317-
return `
318-
<hostdev mode='subsystem' type='scsi'>
319-
<source>
320-
<adapter name='${adapterName}'/>
321-
<address bus='${bus}' target='${target}' unit='${unit}'/>
322-
</source>
323-
</hostdev>
324-
`.trim()
325-
},
326-
248+
// HBA 디바이스 텍스트에서 SCSI 주소 정보 추출
327249
getHbaInfoFromDeviceText () {
250+
// 여러 가능한 속성에서 SCSI 주소 찾기
328251
let deviceText = ''
329252
330253
if (this.resource.hostDevicesText) {
@@ -335,6 +258,7 @@ export default {
335258
deviceText = this.resource.text
336259
}
337260
261+
// SCSI 주소 패턴 매칭 (다양한 형식 지원)
338262
const scsiAddressMatch = deviceText.match(/SCSI Address:\s*([0-9:]+)/i) ||
339263
deviceText.match(/scsi[:\s]*([0-9:]+)/i) ||
340264
deviceText.match(/([0-9]+:[0-9]+:[0-9]+:[0-9]+)/)
@@ -349,6 +273,7 @@ export default {
349273
return null
350274
},
351275
276+
// 다중 HBA 할당 처리
352277
async handleSubmit () {
353278
if (!this.form.virtualmachineid) {
354279
this.$notification.error({
@@ -358,38 +283,6 @@ export default {
358283
return
359284
}
360285
361-
// VM 상태 확인
362-
try {
363-
const vmResponse = await api('listVirtualMachines', {
364-
id: this.form.virtualmachineid,
365-
listall: true
366-
})
367-
const vm = vmResponse.listvirtualmachinesresponse?.virtualmachine?.[0]
368-
369-
if (!vm) {
370-
this.$notification.error({
371-
message: this.$t('label.error'),
372-
description: 'Selected VM not found.'
373-
})
374-
return
375-
}
376-
377-
if (vm.state !== 'Running') {
378-
this.$notification.warning({
379-
message: this.$t('message.warning'),
380-
description: `VM must be in Running state for HBA device allocation. Current state: ${vm.state}`
381-
})
382-
return
383-
}
384-
} catch (error) {
385-
console.error('Error checking VM state:', error)
386-
this.$notification.error({
387-
message: this.$t('label.error'),
388-
description: 'Failed to check VM state.'
389-
})
390-
return
391-
}
392-
393286
this.loading = true
394287
try {
395288
// 선택된 VM의 상태 확인
@@ -411,12 +304,14 @@ export default {
411304
return
412305
}
413306
307+
// HBA 디바이스 상세 정보 가져오기
414308
const hbaResponse = await api('listHostHbaDevices', { id: this.resource.id })
415309
const hbaDevices = hbaResponse.listhosthbadevicesresponse?.listhosthbadevices?.[0]
416310
417-
// console.log('HBA Devices response:', hbaResponse)
418-
// console.log('HBA Devices data:', hbaDevices)
311+
console.log('HBA Devices response:', hbaResponse)
312+
console.log('HBA Devices data:', hbaDevices)
419313
314+
// HBA 디바이스 데이터에서 SCSI 주소 정보 추출
420315
let scsiAddress = null
421316
let deviceType = null
422317
let isVhba = false
@@ -436,7 +331,7 @@ export default {
436331
// 디바이스 텍스트에서 SCSI 주소 및 WWN 정보 추출
437332
if (hbaDevices.hostdevicestext[deviceIndex]) {
438333
const deviceText = hbaDevices.hostdevicestext[deviceIndex]
439-
// console.log('Found device text for', this.resource.hostDevicesName, ':', deviceText)
334+
console.log('Found device text for', this.resource.hostDevicesName, ':', deviceText)
440335
441336
// SCSI 주소 패턴 매칭
442337
const scsiMatch = deviceText.match(/SCSI Address:\s*([0-9:]+)/i) ||
@@ -464,10 +359,15 @@ export default {
464359
}
465360
}
466361
362+
// 현재 HBA 디바이스를 선택된 VM에 할당
363+
console.log('Allocating current HBA device to VM...')
364+
467365
try {
366+
// SCSI 주소 추출 - resource에서 직접 가져오기
468367
let scsiAddress = null
469368
let deviceText = ''
470369
370+
// 여러 가능한 속성에서 디바이스 텍스트 찾기
471371
if (this.resource.hostDevicesText) {
472372
deviceText = this.resource.hostDevicesText
473373
} else if (this.resource.hostdevicestext) {
@@ -477,9 +377,10 @@ export default {
477377
}
478378
479379
scsiAddress = this.extractScsiAddress(deviceText)
480-
// console.log('Device text:', deviceText)
481-
// console.log('Extracted SCSI address:', scsiAddress)
380+
console.log('Device text:', deviceText)
381+
console.log('Extracted SCSI address:', scsiAddress)
482382
383+
// XML 설정 생성
483384
const xmlConfig = this.generateXmlConfig(this.resource.hostDevicesName, scsiAddress)
484385
console.log('Generated XML config:', xmlConfig)
485386
@@ -511,15 +412,16 @@ export default {
511412
allocationParams.devicetype = 'virtual'
512413
}
513414
514-
// console.log('Allocating with params:', allocationParams)
415+
console.log('Allocating with params:', allocationParams)
515416
516417
const allocationResponse = await api('updateHostHbaDevices', allocationParams)
517418
518419
if (allocationResponse.error) {
519420
throw new Error(allocationResponse.error.errortext || 'Failed to allocate HBA device')
520421
}
521422
522-
this.$message.success(this.$t('message.success.hba.device.allocated'))
423+
console.log('Successfully allocated HBA device to VM')
424+
this.$message.success('HBA 디바이스가 성공적으로 할당되었습니다.')
523425
} catch (error) {
524426
console.error('Failed to allocate HBA device:', error)
525427
throw error

0 commit comments

Comments
 (0)