Skip to content

Commit 5019378

Browse files
committed
Merge pull request #808 from jschoiRR/diplo-2026
[Mold Diplo] guest-get-fsinfo/NIC/Qemu 버전 조회를 각각 독립 예외처리로 분리해, 일부 실패해도 이미 수집된 VM stats는 계속 반환되도록 수정
1 parent f7c2fe3 commit 5019378

2 files changed

Lines changed: 73 additions & 61 deletions

File tree

plugins/hypervisors/kvm/src/main/java/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 68 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5593,82 +5593,91 @@ public VmStatsEntry getVmStat(final Connect conn, final String vmName) throws Li
55935593
String mergeCommand = String.format("virsh qemu-agent-command %s '{\"execute\":\"guest-info\"}'", vmName);
55945594
String result = Script.runSimpleBashScript(mergeCommand);
55955595

5596-
if (result != null) {
5597-
qemuAgentVersion = new JsonParser().parse(result).getAsJsonObject().get("return").getAsJsonObject().get("version").getAsString();
5598-
metrics.setQemuAgentVersion(qemuAgentVersion);
5599-
5600-
result = dm.qemuAgentCommand(QemuCommand.buildQemuCommand(QemuCommand.AGENT_NETWORK_GET_INTERFACES, null), 2, 0);
5601-
if (result != null && !(result.startsWith("error"))) {
5602-
LOGGER.debug(dm.getName() +" >> " + result);
5603-
JsonArray arrData = (JsonArray) new JsonParser().parse(result).getAsJsonObject().get("return");
5604-
for (JsonElement je : arrData) {
5605-
JsonElement nicName = je.getAsJsonObject().get("name") == null ? null : je.getAsJsonObject().get("name");
5606-
JsonElement nicAddrs = je.getAsJsonObject().get("ip-addresses") == null ? null : je.getAsJsonObject().get("ip-addresses");
5607-
if(nicName == null || "lo".equals(nicName.getAsString())) {
5608-
continue;
5609-
} else {
5610-
if (nicAddrs == null){
5596+
if (StringUtils.isNotBlank(result) && !(result.startsWith("error"))) {
5597+
try {
5598+
qemuAgentVersion = new JsonParser().parse(result).getAsJsonObject().get("return").getAsJsonObject().get("version").getAsString();
5599+
metrics.setQemuAgentVersion(qemuAgentVersion);
5600+
} catch (Exception e) {
5601+
LOGGER.warn("Failed to parse qemu guest-info result for VM [{}], keeping default qemu agent version.", vmName, e);
5602+
}
5603+
5604+
try {
5605+
result = dm.qemuAgentCommand(QemuCommand.buildQemuCommand(QemuCommand.AGENT_NETWORK_GET_INTERFACES, null), 2, 0);
5606+
if (StringUtils.isNotBlank(result) && !(result.startsWith("error"))) {
5607+
LOGGER.debug(dm.getName() + " >> " + result);
5608+
JsonArray arrData = (JsonArray) new JsonParser().parse(result).getAsJsonObject().get("return");
5609+
for (JsonElement je : arrData) {
5610+
JsonElement nicName = je.getAsJsonObject().get("name") == null ? null : je.getAsJsonObject().get("name");
5611+
JsonElement nicAddrs = je.getAsJsonObject().get("ip-addresses") == null ? null : je.getAsJsonObject().get("ip-addresses");
5612+
if (nicName == null || "lo".equals(nicName.getAsString())) {
56115613
continue;
56125614
} else {
5613-
JsonElement nicMac = je.getAsJsonObject().get("hardware-address") == null ? null : je.getAsJsonObject().get("hardware-address");
5614-
if (nicMac == null) {
5615+
if (nicAddrs == null) {
56155616
continue;
56165617
} else {
5617-
JsonArray arrData2 = (JsonArray) je.getAsJsonObject().get("ip-addresses");
5618-
for (JsonElement je2 : arrData2) {
5619-
JsonElement nicAddrIp = je2.getAsJsonObject().get("ip-address") == null ? null : je2.getAsJsonObject().get("ip-address");
5620-
JsonElement nicAddrIpType = je2.getAsJsonObject().get("ip-address-type") == null ? null : je2.getAsJsonObject().get("ip-address-type");
5621-
if(nicAddrIp == null || nicAddrIpType== null || !"ipv4".equals(nicAddrIpType.getAsString())) {
5622-
continue;
5623-
} else {
5624-
nicAddrMap.put(nicMac.getAsString(), nicAddrIp.getAsString());
5618+
JsonElement nicMac = je.getAsJsonObject().get("hardware-address") == null ? null : je.getAsJsonObject().get("hardware-address");
5619+
if (nicMac == null) {
5620+
continue;
5621+
} else {
5622+
JsonArray arrData2 = (JsonArray) je.getAsJsonObject().get("ip-addresses");
5623+
for (JsonElement je2 : arrData2) {
5624+
JsonElement nicAddrIp = je2.getAsJsonObject().get("ip-address") == null ? null : je2.getAsJsonObject().get("ip-address");
5625+
JsonElement nicAddrIpType = je2.getAsJsonObject().get("ip-address-type") == null ? null : je2.getAsJsonObject().get("ip-address-type");
5626+
if (nicAddrIp == null || nicAddrIpType == null || !"ipv4".equals(nicAddrIpType.getAsString())) {
5627+
continue;
5628+
} else {
5629+
nicAddrMap.put(nicMac.getAsString(), nicAddrIp.getAsString());
5630+
}
56255631
}
56265632
}
56275633
}
56285634
}
56295635
}
5636+
metrics.setNicAddrMap(nicAddrMap);
56305637
}
5631-
metrics.setNicAddrMap(nicAddrMap);
5638+
} catch (Exception e) {
5639+
LOGGER.warn("Failed to fetch guest network interfaces for VM [{}], continuing without NIC address stats.", vmName, e);
56325640
}
56335641

5634-
result = dm.qemuAgentCommand(QemuCommand.buildQemuCommand(QemuCommand.AGENT_GET_FSINFO, null), 2, 0);
5635-
if (result != null && !(result.startsWith("error"))) {
5636-
// logger.debug(dm.getName() + " >> " + result);
5637-
5638-
JsonArray arrData = (JsonArray) new JsonParser().parse(result).getAsJsonObject().get("return");
5639-
5640-
for (JsonElement je : arrData) {
5641-
JsonObject jsonObj = je.getAsJsonObject();
5642-
JsonElement diskInfo = jsonObj.get("disk");
5643-
5644-
if (diskInfo != null && diskInfo.isJsonArray()) {
5645-
for (JsonElement diskElement : diskInfo.getAsJsonArray()) {
5646-
// Capacity used by disk file system
5647-
JsonObject diskObj = diskElement.getAsJsonObject();
5648-
5649-
JsonElement serialElement = diskObj.get("serial");
5650-
JsonElement usedFsBytesElement = jsonObj.get("used-bytes");
5651-
if (serialElement == null || serialElement.isJsonNull() || usedFsBytesElement == null || usedFsBytesElement.isJsonNull()) {
5652-
continue;
5653-
}
5642+
try {
5643+
result = dm.qemuAgentCommand(QemuCommand.buildQemuCommand(QemuCommand.AGENT_GET_FSINFO, null), 2, 0);
5644+
if (StringUtils.isNotBlank(result) && !(result.startsWith("error"))) {
5645+
JsonArray arrData = (JsonArray) new JsonParser().parse(result).getAsJsonObject().get("return");
5646+
5647+
for (JsonElement je : arrData) {
5648+
JsonObject jsonObj = je.getAsJsonObject();
5649+
JsonElement diskInfo = jsonObj.get("disk");
5650+
5651+
if (diskInfo != null && diskInfo.isJsonArray()) {
5652+
for (JsonElement diskElement : diskInfo.getAsJsonArray()) {
5653+
// Capacity used by disk file system
5654+
JsonObject diskObj = diskElement.getAsJsonObject();
5655+
5656+
JsonElement serialElement = diskObj.get("serial");
5657+
JsonElement usedFsBytesElement = jsonObj.get("used-bytes");
5658+
if (serialElement == null || serialElement.isJsonNull() || usedFsBytesElement == null || usedFsBytesElement.isJsonNull()) {
5659+
continue;
5660+
}
56545661

5655-
String serial = diskObj.get("serial").getAsString();
5656-
long usedFsBytes = usedFsBytesElement.getAsLong();
5657-
if (serial.length() >= 20) {
5658-
//serial to half path uuid
5659-
String serial_val = serial.substring(serial.length() - 20);
5660-
String serial_uuid = serial_val.substring(0, 8) + "-"
5661-
+ serial_val.substring(8, 12) + "-"
5662-
+ serial_val.substring(12, 16) + "-"
5663-
+ serial_val.substring(16, 20);
5664-
serial = serial_uuid;
5665-
System.out.println(serial);
5662+
String serial = diskObj.get("serial").getAsString();
5663+
long usedFsBytes = usedFsBytesElement.getAsLong();
5664+
if (serial.length() >= 20) {
5665+
// serial to half path uuid
5666+
String serialVal = serial.substring(serial.length() - 20);
5667+
String serialUuid = serialVal.substring(0, 8) + "-"
5668+
+ serialVal.substring(8, 12) + "-"
5669+
+ serialVal.substring(12, 16) + "-"
5670+
+ serialVal.substring(16, 20);
5671+
serial = serialUuid;
5672+
}
5673+
fsUsageMap.put(serial, fsUsageMap.getOrDefault(serial, 0L) + usedFsBytes);
56665674
}
5667-
fsUsageMap.put(serial, fsUsageMap.getOrDefault(serial, 0L) + usedFsBytes);
56685675
}
56695676
}
5677+
metrics.setFsUsageMap(fsUsageMap);
56705678
}
5671-
metrics.setFsUsageMap(fsUsageMap);
5679+
} catch (Exception e) {
5680+
LOGGER.warn("Failed to fetch guest filesystem info for VM [{}], continuing without filesystem usage stats.", vmName, e);
56725681
}
56735682
}
56745683

ui/src/config/section/storage.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,12 @@ export default {
292292
message: 'message.action.delete.volume',
293293
dataView: true,
294294
show: (record, store) => {
295+
const isDetached = !record.virtualmachineid
296+
const isDetachedAllocatedRoot = record.state === 'Allocated' && record.type === 'ROOT' && isDetached
295297
return ['Expunging', 'Expunged', 'UploadError'].includes(record.state) ||
296-
['Allocated', 'Uploaded'].includes(record.state) && record.type !== 'ROOT' && !record.virtualmachineid ||
297-
(record.state === 'Ready' && record.type !== 'ROOT' && !record.virtualmachineid) ||
298+
['Allocated', 'Uploaded'].includes(record.state) && record.type !== 'ROOT' && isDetached ||
299+
(record.state === 'Ready' && record.type !== 'ROOT' && isDetached) ||
300+
isDetachedAllocatedRoot ||
298301
((['Admin', 'DomainAdmin'].includes(store.userInfo.roletype) || store.features.allowuserexpungerecovervolume) && record.state === 'Destroy')
299302
},
300303
groupAction: true,

0 commit comments

Comments
 (0)