@@ -62,13 +62,6 @@ import { api } from '@/api'
6262
6363export 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